EECS 373 - Fall 2026 - Lecture 3: Toolchain & ABI — Transcript
Full transcript
- 0:00We're going to be talking about tool
- 0:01chain and the application binary
- 0:02interface.
- 0:05So homework one was due yesterday. Uh
- 0:08today you can do uh submit it late for
- 0:10five or 10 point penalty or 10% penalty.
- 0:13Homework 2 has been posted and is due
- 0:15next week.
- 0:17Um and then we've finally got um room
- 0:20assignments for our midterms and our
- 0:22team formation event. And you won't
- 0:25remember and I I'll remind you later,
- 0:26but uh we'll have a list that defines
- 0:29which people go to which room when it's
- 0:31exam day. I think it's already on the
- 0:33the website, but those are the
- 0:35logistics. Any logistics questions
- 0:37before we begin?
- 0:42Nope. All right. So, talk about uh
- 0:45component of the day. I like this be
- 0:47just because it gives people a breath of
- 0:49a lot of the knowledge that we just kind
- 0:50of assume students know and then maybe
- 0:52some of the students know it and some of
- 0:54the students don't. So um a lot of times
- 0:57we think about batteries from the
- 0:58consumer side where these like
- 0:59predefined nickel metal hydrides.
- 1:01They're super safe. They have the same
- 1:03everything is about the same voltage
- 1:04based on 1.5 volts and they're just kind
- 1:07of like plugandplay. When you get to the
- 1:09embedded systems world, you have a lot
- 1:10more choices. And usually it's in these
- 1:12uh packs and pouches where you're trying
- 1:14to optimize
- 1:16uh your battery performance for your
- 1:18particular device. And so now you got to
- 1:20think about things like runtime and
- 1:22current draw and rechargeability. And of
- 1:25course, one of the key metrics is
- 1:26voltage, but now you have to start
- 1:28thinking about capacity. And they don't
- 1:29you would think that they would talk
- 1:30about capacity in terms of like energy
- 1:33or maybe runtime, but instead they they
- 1:35do it u milliamps per hour, which is a
- 1:38version of um uh capacity or energy. And
- 1:43then they have this other thing that's
- 1:44called a C-rating, and that's how fast
- 1:47you can discharge your batteries versus
- 1:49charge them. And so the higher the
- 1:51C-rating, the more energy you can pull
- 1:53out of it. Not all batteries are are the
- 1:55same, so you got to know what you're
- 1:56you're dealing with. And then the next
- 1:58part is there's battery chemistry kind
- 2:00of defines every one of those terms up
- 2:02there and the number of cells. And then
- 2:04there's nickel metal hydide versus
- 2:06lithium ion. But there's also a whole
- 2:07families of lithium ion. So it's not
- 2:10simple enough just to say I grab any old
- 2:12battery and it'll work. You do have to
- 2:14think through a lot of what how much
- 2:16current is your device pulling out? What
- 2:18are the real voltage requirements to get
- 2:19that all right? So just more of a
- 2:21statement of word of caution. There's a
- 2:23bigger world here when you guys start uh
- 2:25project time. One of the big
- 2:27misconceptions about batteries is that
- 2:29people think, well, whatever's on the
- 2:30label is that's how much voltage it puts
- 2:32out. And that's not the case. It was
- 2:34kind of the case with nickel metal
- 2:35hydrides, which were pretty constant,
- 2:38but uh lithium polymer uh batteries are
- 2:40usually they say like 3.7 volts, but
- 2:43really they'll charge up to 4.2 and
- 2:45maybe they'll discharge down to maybe
- 2:473.3 as a usable. That would be pretty
- 2:49dangerous. Maybe 3.4. Um if you go much
- 2:52lower, they'll uh catch on fire and
- 2:54burn. So you just got to know what kind
- 2:57of batteries you're dealing with and
- 2:58what the expectation is. It's definitely
- 3:00not for lithium ion that you get a
- 3:02stable voltage out. That's why we need
- 3:03regulators.
- 3:05And then just um some safety rules for
- 3:08the lab. You cannot solder well just in
- 3:11general um if you have any questions
- 3:12just ask lab staff. They're willing to
- 3:14help you. But you can't solder
- 3:15batteries. Batteries aren't soldered.
- 3:17They're welded. And that's just a
- 3:19different way of technology of doing
- 3:21things. Um if you try and solder a
- 3:23battery, they'll explode. I had a a
- 3:26fellow student when I was in undergrad
- 3:28who went and soldered up a whole big
- 3:30battery pack of nickel metal hydrides.
- 3:32They got hot cuz he was soldering them
- 3:34and then they exploded all over him and
- 3:36then he had, you know, um battery acid,
- 3:38basically powdered battery acid all over
- 3:40his clothes and it burned him slightly.
- 3:41I mean, he was fine, but just don't do
- 3:43that. Um all batteries, especially
- 3:46lithium ion, should have um battery
- 3:49protection. So, you might see these
- 3:50little circuits on them. These are to
- 3:52protect against a short circuit event.
- 3:54So if you by accident short it out, they
- 3:57don't want the battery to uh start
- 3:59discharging a lot of current, go into
- 4:02thermal runaway, and then start burning.
- 4:04And so you may remember that uh Boeing
- 4:07had a bunch of plane fires that
- 4:08occurred, right? Um and that was poorly
- 4:12designed batteries that got hot and had
- 4:14thermal runaway. Um, so they have these
- 4:16circuits on here that will disconnect um
- 4:19the battery if it's a short circuit. And
- 4:21so sometimes you'll find cells that you
- 4:22think are dead. Not cells, packs that
- 4:25you think are dead. It may not actually
- 4:26be dead. It's just that it was drawn too
- 4:28much current at one point. Um, but so
- 4:31don't play with those things. That's
- 4:32that's not where we're at in this
- 4:34particular uh lab. So you should be
- 4:36soldering blank cells. You shouldn't be
- 4:38disassembling things. You should
- 4:39probably be over here where you have a
- 4:40pack or something that already has a
- 4:42plug on it that's already ready to go.
- 4:44This is where you should be uh working
- 4:46with in the lab. If you have questions,
- 4:48ask James or the IAS. They'll they'll
- 4:50point you in the right direction if you
- 4:52need some weird custom thing. Any
- 4:54general questions about batteries?
- 4:59Do we all know this already? Were you
- 5:01like, nah, we don't need this. Somebody
- 5:03learned something.
- 5:05I heard I see some head shaking.
- 5:07Fantastic. Okay. Uh so yeah, don't
- 5:10solder things.
- 5:12Okay, so recap from last lecture. We
- 5:14talked about some of the background of
- 5:15ARM uh some of the naming conventions
- 5:18and remember it the point of me telling
- 5:20you that was to for you to understand
- 5:23the architecture and why it was designed
- 5:25that way. It's good to understand the
- 5:26business model. If it was just a company
- 5:28like Intel, they don't need to make an
- 5:31ISA that uh can be used by everyone.
- 5:34They're just going to make one version
- 5:35for that particular product they're
- 5:36going to send out. They'll make special
- 5:37commands for whatever chip they're going
- 5:38to make. But that's not the
- 5:40architecture. That's not the business
- 5:41model of ARM. And so, sorry, that's not
- 5:43the business model of ARM. So,
- 5:44therefore, that's not the architecture.
- 5:46They're trying to be a general thing to
- 5:47everyone. And so, once you understand
- 5:49their design choices, it'll help you
- 5:51reason through uh problems and
- 5:53challenges you'll like face designing
- 5:56embedded systems. And when we talked
- 5:58about the ISA, we talked about memory
- 5:59layout and registers and some of the
- 6:01instructions and we went through an uh
- 6:03an example. So today we'll talk about uh
- 6:06tool chains a little bit and application
- 6:09binary interface talking about calling
- 6:11sub routines and stack
- 6:13and we'll start off with this I'm sure
- 6:15you've seen this before but we have this
- 6:17mental model of we have a highle C
- 6:19language that gets compiled into
- 6:20assembly I'm sure you've seen that
- 6:23before and then in assembly you go and
- 6:26have to turn that into machine code and
- 6:28so some of what you're doing in lab and
- 6:29what we're talking about today is kind
- 6:30of like this process of how do we go
- 6:32from a seed to assembly to uh machine
- 6:35code. What does that actually look like?
- 6:38And so one of the blessings or curses of
- 6:41where you are in the embedded systems
- 6:42world is now we have these highle tools
- 6:45that obiscate a lot of those details
- 6:47away. When you're in here, uh you know,
- 6:50you are at the there are so many helper
- 6:52functions that are hiding the lowest
- 6:54level of like I'm going to put
- 6:57instructions in this particular part of
- 6:59memory and those will get read out.
- 7:02I understand why we're doing that. When
- 7:03I started, it was simple enough that you
- 7:05could actually remember the register
- 7:07codes for every, you know, the the
- 7:09actual addresses for certain functions
- 7:10and you would just write them from
- 7:11memory. But now things are so complex
- 7:13that if we taught you all that, if we go
- 7:15from the bottom up, we may never get to
- 7:17the to the more interesting stuff. But
- 7:19if we start just at the high level,
- 7:20you'll never learn what's underneath. So
- 7:22that's we're trying to bridge that gap
- 7:23in this class. So one thing to think
- 7:25about is that there are lots of ARM
- 7:27tools out there just like the one I
- 7:29showed you and the ones you use in lab.
- 7:31But underneath almost all of them is GNU
- 7:33radio or not uh not GNU radio GNU uh uh
- 7:37CC and GCC. These are tools that have
- 7:40been around since the 80s that are the
- 7:43lowlevel compiler chains for an old OS
- 7:46system nobody uses anymore but now it's
- 7:48been adopted by the embedded systems
- 7:49community. It's all open source. So
- 7:51underneath almost every one of them and
- 7:53I'm pretty sure it's everyone I couldn't
- 7:54highlight I couldn't prove it for each
- 7:56one there's this underlying framework
- 7:58and once you understand what that
- 8:00framework is doing you can reason about
- 8:01what the tools are doing
- 8:04so the GNU ARM tool chain is built on uh
- 8:08compilers it's built on binary utilities
- 8:11it's built on debuggers and it's built
- 8:13on a bunch of standard libraries again
- 8:15this is all open sourced and what your
- 8:17tool chain is doing is it's taking your
- 8:20C files that you write uh assembly files
- 8:22and other object files that other people
- 8:24have written maybe or you've written uh
- 8:26your library things and then in the
- 8:28compile stage it's taking all that
- 8:30information along with the we call the
- 8:32memory layout or the floor plan of where
- 8:34all that information goes and it's going
- 8:36and creating some executable images. One
- 8:39of those images is a binary file and one
- 8:41is your disassembly list. The binary
- 8:43file is the actual binary instructions
- 8:46that go into memory and your
- 8:48disassembled list is what your debugger
- 8:50uses to interpret um what's happening on
- 8:52that binary file. So the the this
- 8:55disassembled list stays in your IDE but
- 8:58it's when you're doing boundary scans
- 9:00and walking through code that list is
- 9:02interpreting what's happening in the
- 9:04binary file.
- 9:09>> Yeah.
- 9:10>> C executable without debug don't create
- 9:16>> uh I'm sure that's an option file in
- 9:18your um your IDE to do you want to
- 9:21actually make the uh disassembled by
- 9:23default you always do it and you only
- 9:25just grab the the thing out of the right
- 9:26folder right they put them in different
- 9:27folders
- 9:32any other questions
- 9:36all right so we'll go through an example
- 9:38here and the goal here is to think
- 9:40through a simple program like How does
- 9:42this get interpreted by your compiler or
- 9:47your assembler and your linker into
- 9:48something that would actually be put on
- 9:50a microcontroller? So here we're going
- 9:52to start off with there are some
- 9:54directives. So directives are
- 9:56instructions that tell the assembler
- 9:58what to do. They're not instructions for
- 10:00the core or for the processor, but they
- 10:02tell the assembler you should do these
- 10:04tasks. Then we have labels. So labels
- 10:06are places in code that when the
- 10:09assembler turns it into machine code, it
- 10:12goes and resolves those uh labels into
- 10:14actual addresses.
- 10:16And then we have the code itself. So
- 10:18we'll go through each one of these. So
- 10:20here we have a directive. This is just
- 10:22global start exposes the global start
- 10:24symbol. We have two directives we'll
- 10:28talk about. So space and bite. So space
- 10:32space is a tool is a directive that
- 10:35tells the assembler I just want you to
- 10:36put white space or all zeros. So imagine
- 10:39that you have extra space after uh the
- 10:42assembler has put down some code
- 10:44somewhere and then you have you need
- 10:45need blank space. I don't know why but
- 10:47often times you do um probably because
- 10:50some other function expects uh like on a
- 10:52word boundary let's say um that the next
- 10:55piece of information is there. So you
- 10:57can use space to fill in zeros.
- 11:00Byte is a method that allows you to
- 11:02place bytes in memory.
- 11:06So here we're literally just saying
- 11:08start at the at 0000 in this particular
- 11:11example. Start at memory location 00.
- 11:14Start by putting in blank space and then
- 11:16lay down these bytes one after each each
- 11:18other. We're putting data into memory.
- 11:24Then we have move. We talked about move
- 11:26uh a bunch last lecture but just to
- 11:29review. So we have move registers that
- 11:31just takes data from one register and
- 11:32puts into another register. We have move
- 11:35immediate which is a little bit more
- 11:36useful. So the T1 encoding allows you to
- 11:39take eight bits and put it in one of the
- 11:40lower registers. We have the T2 encoding
- 11:43which allows you to do constants. This
- 11:45isn't really important for you to
- 11:46remember. It's just to point out that uh
- 11:49remember the challenge was we could not
- 11:50make 32-bit words in a 32-bit
- 11:53instruction. there's just not enough
- 11:54bits to fit in there. And so ARM has
- 11:57given us the functionality to create a
- 12:00subset of 32bit words, right? Using
- 12:02these patterns. So you could have
- 12:04repeating things, you could have um
- 12:06different bits in different locations.
- 12:08That does give you some some flexibility
- 12:10to make constants. This is good to know
- 12:12that exists. Um and then we have move
- 12:16wide. Remove wide was the way we uh make
- 12:19a 32-bit uh immediate and then we um put
- 12:2316 bits in the lower side and then put
- 12:25all zeros in the upper.
- 12:29And then it's also important to remember
- 12:31that there's two uh differences here.
- 12:34There's move wide which is ovw and then
- 12:36there's move.w.
- 12:38Thew you may have seeing in your
- 12:40assembler is just stating make this it's
- 12:43telling the assembler this must be a
- 12:4532-bit instruction. It could possibly
- 12:48the assembler could choose I want to be
- 12:49more efficient and put in a 16- bit
- 12:52instruction. Uh so it might be able to
- 12:54do uh T1. I don't know why but I'm sure
- 12:57there's a good reason. Uh but you could
- 12:59direct it to say I want you to
- 13:01specifically use a 32-bit instruction
- 13:03even though it could fit in a T1. So
- 13:05that's just a difference. uh the dot at
- 13:07the end defines it's a Y uh 32-bit
- 13:09instruction. The move w assigns it has
- 13:11speci specific functionality
- 13:16and then we talked about this last uh
- 13:19last week but move top is a special
- 13:21function move t oops where uh you take
- 13:25the 16- bit values and put it in the top
- 13:28of the the register um and keep whatever
- 13:32is in the register at the lower uh the
- 13:34lower 16 are kept. So this is a way with
- 13:36these two instructions to place a 32-bit
- 13:39word into a register with two
- 13:41instructions. Yes.
- 13:43>> The
- 13:45space and bite expression. How does it
- 13:46know where to place?
- 13:48>> What's that?
- 13:48>> The space and bite expression. They put
- 13:50either zeros or some data. How does it
- 13:52know where
- 13:53>> ah we are dead simple. We are at we are
- 13:56like sticks and rocks. It is saying at
- 13:59location 0000.
- 14:02We're going to give that location the
- 14:03label global start. And then at location
- 14:060000, we're going to put eight bytes
- 14:08worth of uh zeros.
- 14:12And then at the next location, we're
- 14:14going to have a label data. And we're
- 14:16going to put those four bytes of data at
- 14:18that location.
- 14:23Now, your linker may have special rules.
- 14:25that says, "Okay, well, you'll learn
- 14:27later on like um the envic table has to
- 14:31go at 000." There's certain things that
- 14:33have to go at locations in memory. We're
- 14:34just assuming this is just a bare
- 14:36processor. There's no extra special
- 14:38stuff, but this is how it would be
- 14:39defined. Something has to start, you're
- 14:40going to start at zero.
- 14:43Uh we have some other directives here.
- 14:44So, um
- 14:47lower 16 and upper 16 allow you to take
- 14:50data out of memory and put it into
- 14:52somewhere.
- 14:54So here just this is allows us to when
- 14:57you couple it with move wide move top.
- 14:59So we're instead of getting data as
- 15:02defined by a register um an immediate or
- 15:06a move right we're getting data at a
- 15:08label. So that's what this allows this
- 15:10to happen. What label is this? Well the
- 15:12label here is data and data is there.
- 15:17Okay. And then we have uh now we're back
- 15:20down to like our normal functions here.
- 15:21So here we're loaded some values up. We
- 15:24have a zero here. We have another zero
- 15:26here. And then we've loaded some values
- 15:28into R1. Uh there then we're going to lo
- 15:32do a lower load instruction. So again
- 15:35this is load from the perspective of the
- 15:38core not the perspective of memory. So
- 15:40in core you're going to load data from
- 15:41memory into uh the core and you're going
- 15:44to put it into some registers. And then
- 15:47we just have to remember that we have
- 15:48load bite versus load sign different
- 15:52versions here. And you could do load
- 15:53halfword or or a full 32-bit word.
- 15:58And then we have adds. And then the
- 15:59other one that kind of review from yes
- 16:01uh last week was compare. So compare is
- 16:04just a function that compares two
- 16:05values. It doesn't have an output
- 16:07register per se. All it does is uh sets
- 16:10the ALU flags or the program status
- 16:13register flags. And then when branch
- 16:15goes through, branch is going to say um
- 16:18it's going to use uh these uh pneumonic
- 16:21extensions to define some functionality.
- 16:24So here if it's uh it was branch equal
- 16:26then if that flag is set it's going to
- 16:28actually branch otherwise it's going to
- 16:30do something else.
- 16:32All right. So uh we have worksheets for
- 16:35you somewhere. So we're going to walk
- 16:38through this program figure out what
- 16:41happens.
- 16:43So, here we go.
- 16:48>> A few minutes later.
- 16:52>> All right, let me help out for a second
- 16:53because I may have misspoke a little
- 16:55earlier. So, let's review where we're at
- 16:59here at global. We're just going to say
- 17:02that 00 0. This is the beginning of
- 17:04memory. Okay. And then we're going to
- 17:06place eight bytes worth of space. Those
- 17:08are going to right in those memory
- 17:10locations, right? Then right after that
- 17:13the bite instruction
- 17:15places data at or places uh hex 12 at
- 17:20that location in memory and then it
- 17:23indexes over one puts another bite.
- 17:26Okay, how we feel about that?
- 17:29We got eight zeros. Then we got some
- 17:32data. Okay,
- 17:36everybody good? Okay, the tricky part is
- 17:40that this here. So, first we know that
- 17:42move, right? Move is just going to go
- 17:44and put zero into R0. It's going to put
- 17:46zero into R4. This lower 16 is not the
- 17:50lower 16 of the data [snorts] at uh
- 17:56data, right? It's not the hex 12, hex 20
- 18:00or 20, hex 201. It is the labels memory
- 18:04location. So we're going to move in the
- 18:07lower 16 bit values of the memory
- 18:10location that's defined by the label
- 18:12data. Then we're going to move up the
- 18:15[snorts] memory the upper 16 of the
- 18:17address that's defined the location of
- 18:20data.
- 18:22How we feel about that?
- 18:24>> Yeah.
- 18:29>> What's that? Why is so data zero?
- 18:34>> Data is no data is at some place
- 18:38location
- 18:42[clears throat]
- 18:44and you can just count where that
- 18:46address is
- 18:48your compiler doesn't know didn't count
- 18:51for you. So the the question is saying
- 18:54we're going to find out the address the
- 18:56data resolves to by using lower 16 and
- 19:00upper 16 [snorts] and then we're going
- 19:03to put that address will now be in R1.
- 19:12You guys are looking at me like I'm
- 19:14crazy, but you're not asking questions.
- 19:16That's scary.
- 19:20>> Yeah. Is it left to right be like 20
- 19:25minutes?
- 19:26>> Yeah, because it's an individual
- 19:27command. We started at some some memory
- 19:30location say three and then we went and
- 19:32put some data down and then we did the
- 19:34next one by construction. Put some data
- 19:36down.
- 19:38All right. [clears throat]
- 19:39Go keep on working. You have questions,
- 19:41let me know.
- 19:42>> Eternity later.
- 19:44>> All right. I saw some good numbers out
- 19:46there.
- 19:47>> Let's see. What do we get for
- 19:52Let's see here. I'm writing five slide.
- 19:55So, I obviously pointed out to you that
- 19:57I'm a tricky, horrible professor who
- 19:59mixed decimal and hex in there to to to
- 20:02make your lives worse. Very good at
- 20:04that. Uh what about R0 at the end? What
- 20:06is R0 going to be?
- 20:08>> Four. And we can kind of you don't even
- 20:10have to really know the program that
- 20:11well. You know that we start at zero.
- 20:13Looks like we're incrementing and then
- 20:15you have to have the comparison at the
- 20:16end. Okay, good. What about uh what else
- 20:19did we need? We needed R2.
- 20:22[snorts]
- 20:25Anybody?
- 20:26>> Yeah.
- 20:27>> I got X and
- 20:29>> Yep. All right.
- 20:31And then what about R4?
- 20:35>> Yeah.
- 20:37>> 145.
- 20:38>> 145. Yeah. And hex. And so, okay. So, we
- 20:41can walk through this real quick. So uh
- 20:43we have zero in put into R0 in R4. We've
- 20:48got the address of data. So data
- 20:52remember is a label. That's just another
- 20:54phrase for an address. So that address
- 20:56is pointing to where this data is. And
- 20:59we put that address through this
- 21:00horrible little directive mechanism here
- 21:03into R0 or I mean R1. And so now when we
- 21:06do our load bite, we're going to load
- 21:09data from memory location defined by R1
- 21:12into R2. And [clears throat] then we're
- 21:14going to increment by one afterwards.
- 21:17And then once it's in there, we're going
- 21:18to add some things together, add some
- 21:20more things together, and compare. We're
- 21:23going to loop through that four times
- 21:25until uh R0 equals 4. And then we're
- 21:29going to branch into dead loop. How do
- 21:31we feel about that?
- 21:34Yeah.
- 21:39The address where data is where the
- 21:42label the address that data resolves to.
- 21:46Sorry, I'll say it again. The address
- 21:48that the label data resolves to.
- 21:56>> You can just walk through that. I think
- 21:58it's nine.
- 21:59>> I know we Yeah.
- 22:03lower.
- 22:07>> Ah, so you might be pointing out you
- 22:10could get away with it but with just
- 22:11lower. Is that your point?
- 22:15>> I guess
- 22:23because I can't have an instruction that
- 22:24will load 32 bits in. Okay.
- 22:26>> Right. Um because it's 32 instruction I
- 22:29can't fit that many bits in. So we're
- 22:30going to break it up into two steps. And
- 22:32we don't necessarily know where data is,
- 22:36right? Data could have been because the
- 22:38linker put it somewhere else. And so
- 22:40this is a way to resolve the val the
- 22:43address that represents data and then
- 22:45put it into register.
- 22:52Yeah.
- 22:56What else?
- 23:00Okay.
- 23:03Why why would it be a good idea to use a
- 23:05dead loop
- 23:07and it's in a program this simple? What
- 23:09will happen if you don't?
- 23:13[snorts]
- 23:16What do we think?
- 23:21Yeah.
- 23:28>> What's going to happen? If you didn't
- 23:29have dead loop, it's just going to go
- 23:30start go to the next instruction. PC is
- 23:33going to increment by four. It's going
- 23:34to pull whatever's in memory and it's
- 23:35going to start executing it. And that
- 23:37could be anything, right? So your your
- 23:40thing's going to go haywire. Um I don't
- 23:42know if anybody looked like retro games,
- 23:45right? Like uh Nintendo 64 Mario, right?
- 23:48They're they're like they have all these
- 23:50little or no uh NES Mario, right? They
- 23:52have all these little hacks where
- 23:53they're like actually executing not
- 23:55instructions like they like there's lost
- 23:57worlds where it's like they're actually
- 24:00in uh executing
- 24:02um uh graphics space. They found a bug
- 24:05and now they get to play Mario in
- 24:06graphics space and it's like random
- 24:08random things happen because it's nobody
- 24:10intended the PC to ever point there. So
- 24:13anyways,
- 24:14okay. Any last questions in that
- 24:17example? Is that example horrible?
- 24:20Supposed to say yes. Horrible.
- 24:24>> Yeah.
- 24:28>> Um why we starting with the one?
- 24:35>> Oh my god. So here I wrote this as a
- 24:38word.
- 24:39>> There it's written as
- 24:42And so the bite instruction says first
- 24:44first location put X12 down then goes
- 24:48increment up the next memory location
- 24:51you put 20 [clears throat]
- 24:53then when I wrote it there I wrote it as
- 24:55a word so it puts the location I'm
- 24:58tricking you or at least farm is
- 25:00tricking you system is tricking you
- 25:04okay good question all right so let's
- 25:07move on to the application binary
- 25:09interface so this is um you know
- 25:12Is this a contract between the
- 25:14programmers and the hard of how to share
- 25:16the hardware resources? So if you follow
- 25:18these rules, you know that the libraries
- 25:21that you're going to call are still
- 25:22following these rules. So not
- 25:23everybody's going to play nicely
- 25:25together, but there are clearly there
- 25:26could be uh issues if you didn't. So the
- 25:29goal is to be able to uh compile
- 25:31separate binaries that work together.
- 25:34And this includes uh conventions around
- 25:36calling functions, data layout, object
- 25:39format, stack behavior like all the
- 25:42intricacies of how to run a program are
- 25:44defined by the application binary
- 25:45interface.
- 25:47And so what resources are you sharing?
- 25:49So uh we have we have limited set of uh
- 25:51registers. We're not going to virtualize
- 25:53these. These are all we're going to get
- 25:54on this core. And so when a program uh
- 25:58is calling another function, you have to
- 26:00have some agreement about well what's
- 26:01the expectation about how this thing is
- 26:03going to be used. So um you know what
- 26:06are some concerns you have? You're going
- 26:07to write you're going to call this
- 26:08[clears throat] program that was or
- 26:09function is called written by somebody
- 26:11else. What would you be concerned about
- 26:14uh if you weren't sharing resources
- 26:16together and what rules would you come
- 26:17up with? So why don't you take 30
- 26:18seconds brainstorm a little bit? What do
- 26:20you have to worry about?
- 26:23Heat.
- 26:25Heat.
- 26:58All right. What do we think? What are
- 26:59some things that you would be concerned
- 27:01about?
- 27:07zero concerns. Yes. One concern.
- 27:11>> Like how?
- 27:16>> Yeah.
- 27:21>> And what are some what are some rules we
- 27:23could put in place about sharing nicely
- 27:24between functions?
- 27:28>> Which which registers you think would be
- 27:30a good idea?
- 27:34No, no. Like, uh, of these registers,
- 27:36which ones would you just say, "Okay,
- 27:38we're going to let the function have
- 27:40control over
- 27:43do you say the function should restore
- 27:44everything?"
- 27:47>> Yeah.
- 27:50>> Okay. Just come up with some rules,
- 27:52right? Uh, it's it's going to be not is
- 27:54we're not going to uh uh it's going to
- 27:57be slightly different than that, but
- 27:58yeah, we have to come up with a set of
- 27:59rules. Okay, so uh caller save registers
- 28:04are R0 through R3. So these are
- 28:06intentionally scratch space. The the
- 28:09function that you're calling can write
- 28:11this data and this doesn't have to be
- 28:13preserved. Um
- 28:16so arguments that are passed to the
- 28:19function should be passed through R0
- 28:21through R3 starting with R0. Okay, so
- 28:25sorry parameters or values that are
- 28:26passed uh through it. If you need
- 28:29additional space, that's what the stack
- 28:30is for. So if you wanted to put more
- 28:32than 16, um, you do that in a stack. You
- 28:36could also use a memory value return or
- 28:39a location in memory. So a function
- 28:42return. So the idea is that the uh
- 28:47function should only return one value.
- 28:49Now we break that a little bit, but if
- 28:50it's a 32-bit value, it goes in R0. If
- 28:53it's a 64, it's R0 and R1. And if it's
- 28:57128, then it would be R0 to R3. Okay?
- 29:00And that's also that function scratch
- 29:02space. So we're going to pass variables
- 29:04in with the lower four and we're going
- 29:05to return variables with the lower four.
- 29:08Now ARM's way of thinking about this is
- 29:11it's only one single value. However,
- 29:13they give you the nice caveat that it
- 29:14can be a containerized vector. What the
- 29:17heck what does that mean? It just means
- 29:19you could have four values in there.
- 29:20That's what it means functionally for
- 29:22this class. You can have four little
- 29:23values in there. If you need anything
- 29:25else, then you're going to have to use a
- 29:27memory address. It could be the stack.
- 29:29And so, uh, say you needed to get back a
- 29:32large array, uh, the function would say,
- 29:34okay, here is the memory location where
- 29:36I want this data. The function would
- 29:38store that data there. And then when it
- 29:40returns, the, uh, calling function, uh,
- 29:44could go to that memory location and
- 29:45pull the data out. And this is just a
- 29:48graphical, uh, view of what that looks
- 29:50like.
- 29:53Uh so inputs are all R0 through R3 and
- 29:56then you have some subruine and then
- 29:58it's supposed to be putting outputs back
- 30:00and again it has this idea that you only
- 30:01have one output even though it could be
- 30:03a vectorzed output. Essentially this
- 30:05really means that it should always
- 30:06expect 48 bits for that fun or 128 bits
- 30:09for that function. This should never be
- 30:11a variable number of uh bits coming
- 30:14back. Yeah. Sorry. Can you explain what
- 30:17the containerized vector?
- 30:18>> The containerized vector is just ARM's
- 30:20way of saying okay we expect a 128 value
- 30:24bit value always coming back from this
- 30:26function. It's never going to be
- 30:27dynamically allocated. It's not going to
- 30:29be one time say 32 and then 64 and
- 30:32something else. We're always expected
- 30:33this chunk of 128 bits. Um, but you as
- 30:37the user of this uh knowing how the
- 30:40function is written, it could have uh
- 30:44four 32-bit values in it. It's just it
- 30:46can't be a variable size uh container.
- 30:50>> Explain the last bullet point.
- 30:52>> The last bullet point. Yeah. Makes me
- 30:54assume I know what the last bullet point
- 30:56was. Okay. So, it's not technically this
- 31:00is it's when they say when you look at
- 31:01the spec, it's not technically for
- 31:02independently returned values. means
- 31:04that they are not supposed to be
- 31:06dynamically changing number of bits.
- 31:08It's not like one time it's only valid
- 31:10to put back R0 but then another call the
- 31:13function it should be R1 and R0 it means
- 31:15that it's a containerized that we always
- 31:17expect one value to come back. So it
- 31:19technically they're not independent
- 31:21variables right even though you can
- 31:23interpret them as four different values.
- 31:30And then uh we had this small piece of
- 31:33information came up multiple times over
- 31:35the years. Um so the standard is called
- 31:38the AA uh PCS. I don't even know what
- 31:41the how to say the acronym, but that's
- 31:43not what the uh um manual is called
- 31:47because somewhere in the past it used to
- 31:49be called the ARM architecture
- 31:52procedural call standard and then some
- 31:54reason they switched it but every
- 31:55engineer all calls all the old timers at
- 31:58your uh new jobs are going to call it
- 31:59the AAPCS.
- 32:01So just know that they did that trick to
- 32:03you to trick you. I don't know why they
- 32:05did it.
- 32:08All right, moving along. So other bits
- 32:10about procedure calls. So the collie
- 32:13save registers are R4 through R11. These
- 32:16the function must preserve. So a
- 32:18function may need of course more than
- 32:20four registered for some operation. Its
- 32:22job is it has to push that to the stack.
- 32:25That's the preferred function. Put those
- 32:26values in the stack and then u put them
- 32:29back before it returns. And here we have
- 32:31a stack which grows down and increments
- 32:34by four.
- 32:37Um finally there's the uh function
- 32:39called link register. So link register
- 32:41is the way in which you will uh get back
- 32:43from your functions. So branch uh l will
- 32:47set the link register and branch uh
- 32:50register LR. So this is branch to a
- 32:52register what register the LR register.
- 32:54And this returns so when you're
- 32:55returning from your function you will go
- 32:57back to wherever the link register uh
- 32:59points you to. And so we can see this
- 33:02here is this BL is just label um and
- 33:06tells it to go to a particular location
- 33:08and updates the link register.
- 33:11And again just what I said BXLR is
- 33:14basically just take the link register
- 33:16and put it into the PC.
- 33:19Any questions?
- 33:24Okay. So there's some special cases. uh
- 33:27R9 it's a platform specific register
- 33:31platform is kind of a a weird term
- 33:33depending on the state of your
- 33:34microcontroller it may be the static
- 33:36base register it may be the thread
- 33:37register we're going to assume that it's
- 33:39just a normal register that is uh what's
- 33:41one of the three functions you can be so
- 33:43for the purposes of 373 R9 is just a
- 33:47collie saved register but you will see
- 33:49in the documentation is having multiple
- 33:51functions the other uh edge condition
- 33:53that we'll talk about uh later on when
- 33:55we get to interrupts is the
- 33:57interprocedural call register. This is a
- 33:59caller safe register. It's a scratch
- 34:01space. You as programmers that are
- 34:04handcrafting the most beautiful
- 34:06functions in the world should probably
- 34:07not worry about this. This is really a
- 34:09scratch space for your link register or
- 34:11your linker to do its work. But it's
- 34:14just good to know that it is uh caller
- 34:15safe.
- 34:17All right. And this is a graphical
- 34:20demonstration of that. And again, we're
- 34:22assuming R9 is in V6 mode, which is just
- 34:25um a normal environmental register. And
- 34:28then R12 is that special one. And then
- 34:30of course, R13, R14, R15, those have
- 34:32special functions and can't be
- 34:34overwritten. All right, it's kind of a
- 34:37review of 373 with some new wrinkles.
- 34:39What questions do you have before we go
- 34:41to an example?
- 34:46Okay, so we'll go through a basic
- 34:48function call. So here's an example
- 34:51we're going to uh uh square two numbers.
- 34:54So in this example we we're showing
- 34:57here's the uh how we're going to
- 34:59construct the um
- 35:02uh c into uh assembly. So we're going to
- 35:05pass values in normally you say x or y
- 35:08here we're those get resolved to the
- 35:10lowest uh register value to pass it into
- 35:12the function and again the next uh
- 35:15incremental value. So R1 and then it's
- 35:18going to be returned through R0 and then
- 35:21this trip somebody up one year. So this
- 35:23is not part of this intended function.
- 35:24This is just proof. This is helps with
- 35:26the function uh helps with the example.
- 35:29Okay. So here we have assembly code, we
- 35:32have registers and we have memory. Now
- 35:34technically the assembly gets resolved
- 35:36into um instructions which you see over
- 35:39here, right? Those are the instructions.
- 35:41But it's just helpful to think about it
- 35:43here and then we'll walk through memory
- 35:45locations there. So this is it's
- 35:47essentially the same data. So okay,
- 35:49we're going to start off the the program
- 35:51counter is pointing somewhere. For
- 35:52whatever reason, the linker put this at
- 35:54this location in memory. And so we have
- 35:57uh we're going to start here. We have uh
- 35:59we're going to move the the immediate
- 36:01value of three into R0. So we're going
- 36:04to execute that. And now we've
- 36:05incremented this value to here. And then
- 36:07we're going to increment the program
- 36:09counter. And then we're going to load
- 36:11four into R1.
- 36:14All right, that was just figuring out
- 36:15our our variables or setting up our
- 36:17variables. Now we're going to call our
- 36:18function. So, uh, we're going to branch
- 36:22to the location defined by SS SQ, right?
- 36:26And that is a label and that's just a
- 36:28memory address. And that memory address
- 36:29happens to be over here. And then uh
- 36:32I've just labeled it here just so I
- 36:34remember where that is. Okay, so we're
- 36:36going to jump. And now because we did a
- 36:39branch uh link we've updated the link
- 36:42register and now the next value after
- 36:45the function that we called the next
- 36:47value of 1 3 4 that memory location is
- 36:49put in the link register and this will
- 36:51allow the function to know where to
- 36:53return to when it ends.
- 36:57Uh then we uh go let's see wait yeah yep
- 36:59that happened and now we're going to go
- 37:00and execute the first line of the
- 37:02function uh square and so now we're
- 37:05going to multiply r0 * r0 and place it
- 37:08r2 and then we're going to do r1 into r1
- 37:12and place it into r3 we're going to add
- 37:14those together.
- 37:17Now it probably would have been more
- 37:18efficient to say we're going to put this
- 37:19into r0 but we didn't. Doesn't really
- 37:21matter. And then we're going to go place
- 37:23that into r0.
- 37:26And then we're going to branch to the
- 37:28link register. This is branch register
- 37:30which is the X. And we're going to do
- 37:32that into link register. So here we go.
- 37:35And then the value that's in L and LR is
- 37:38going to be placed in the PC. And that's
- 37:40going to kick us back to the location
- 37:43after the branch instruction which got
- 37:46us here. Now we're going to So that's
- 37:48why the the move R R2 or R0 R2 was there
- 37:52just to to prove that point. and then
- 37:54we're going to end. So what any
- 37:57questions
- 38:02review of 370
- 38:05kind of maybe it was a whole summer ago.
- 38:09>> Yeah.
- 38:12>> Sorry.
- 38:28So are you saying the main should Maine
- 38:30have protected itself if there was
- 38:32valuable data there?
- 38:33>> Yes. But that's main Maine's job. It
- 38:37cannot rely on that data being there. So
- 38:39if there's anything value, it should
- 38:40have put it to the stack.
- 38:41>> Okay.
- 38:45>> Right. Oh no, you did. You see, you
- 38:48didn't use R0. That's where you pass
- 38:49back 25. And R2 is where you multiplied
- 38:54uh it. So, you did use it. It's just you
- 38:57didn't have to. You could have rewritten
- 38:58that function so it was more compact,
- 39:01but it wouldn't have mattered from a AI
- 39:04calling point of view.
- 39:09Okay.
- 39:12Any other questions?
- 39:14All right. So for the purposes of this,
- 39:16the program counter, you know, jumped by
- 39:19two or four and the least significant
- 39:21zero was uh bit was always zero. But in
- 39:24reality, that's not how it would work.
- 39:25The program counter always jumps by
- 39:27four. It's when it's that's when it's
- 39:29fetched and when it's decoded, then it's
- 39:31broken into either 16 bit, two 16 bits,
- 39:33or 132-bit instruction. The program
- 39:35counter doesn't know. It doesn't uh it
- 39:37doesn't ever increment by two. Um, also
- 39:41for ARM Cortex M, the the lowest bit of
- 39:44uh the link registers, well, it isn't
- 39:46always one, but it's one for ARM or one
- 39:49for thumb and zero for ARM is tells it
- 39:51what instruction set because the link
- 39:53register can never be uh the lowest bit
- 39:55can never be defined as anything, right?
- 39:58Um, it's so that's a free variable that
- 40:00they're using to say what instruction uh
- 40:03that the the processor is in.
- 40:06And then you can go through and just
- 40:08check your disassembly. Uh this is just
- 40:10a good reminder that if you go and just
- 40:12don't use any flags, right, you will get
- 40:15a lot of crazy code if you ever try to
- 40:17check this thing. And really what your
- 40:18compiler is trying to do is be as safe
- 40:20as possible. It's putting frame pointers
- 40:21in there. Let me go back up here. So you
- 40:23get you're getting frame pointers. It's
- 40:25storing everything up into the the stack
- 40:27if it needs to. But then if you just use
- 40:29the right compiler flags, you can get
- 40:30exactly the same thing out if you uh had
- 40:33wanted to.
- 40:35Okay. So let's review stacks a little
- 40:37bit. So uh we'll go through what the
- 40:41error condition is when you uh call a
- 40:42nonabi compliant function. So here we're
- 40:45going to call the subruine fu.
- 40:48Oh uh no that's not what I'm saying. Oh
- 40:52this is uh what would sorry I got lost a
- 40:54little bit. Uh this would be a violation
- 40:57right because you modified R4 but maybe
- 41:00this function needed to. So how would it
- 41:02get around this? Well, it's the
- 41:03function's responsibility to push R4 to
- 41:05the stack and then at the end pop it
- 41:08back before it branches to um the link
- 41:11register. So, how and the error
- 41:13condition here is that if it doesn't if
- 41:15it clobberers this then you get the
- 41:16wrong value when you add uh one to four
- 41:19over here. But you get the right value
- 41:21if uh you've popped correctly. So, how
- 41:23does uh the stack work? So, we have
- 41:26push. uh push is uh will take the value
- 41:30in a register and push it onto the stack
- 41:32and you can do multiple pushes at a
- 41:34time. Right? So you can do R078
- 41:37but that is equivalent to R 876. It
- 41:40reorders on the fly. So the order is
- 41:43always preserved and this becomes a
- 41:45challenge if you do uh a group of
- 41:48registers if you push them up and then
- 41:50you pop them back individually you
- 41:52better recognize remember that order. So
- 41:54there is an error condition that can
- 41:55occur when handwriting code. And pop is
- 41:58the opposite, right? Pop pulls it back
- 42:00down. Uh the remember the stack always
- 42:02grows and then the act of pushing or
- 42:04popping will increment or decrement the
- 42:07counter or the uh the program stack
- 42:10location. So here we're going to push uh
- 42:13the normally it looks at the last uh
- 42:15valid data. So that was here and then it
- 42:17pushed the value and now it's
- 42:20incremented the counter the program
- 42:22stack counter to the lowest piece of
- 42:24valid data and when you pop you do the
- 42:27reverse pop was pointed at there and
- 42:29then it comes back up.
- 42:31Okay. So one question for you is why is
- 42:35it the push and pop or order invariant?
- 42:38Why is it why would you from an
- 42:40architectural point you're making the
- 42:42the ISA what value would it be to have
- 42:46these uh two instructions be a fun
- 42:49affectionally functionally the same? So
- 42:51why don't you take 30 seconds? Why is
- 42:53this Why did this occur?
- 43:45All right. What do you think? How why is
- 43:47it why did they make it this way? Of all
- 43:49the ways they could have made this
- 43:50instruction, why does it have this error
- 43:51condition in it
- 43:54where order doesn't matter?
- 43:59Yeah,
- 44:00>> I was going to say, you know, there's a
- 44:02limited number of registers. Um, so you
- 44:04could just encode whether or not headed
- 44:08or remove from this deck, right?
- 44:11Um in that way it doesn't matter if you
- 44:14do pop 78 or 68 something like that by
- 44:20the end those bits are going to be.
- 44:23>> That's exactly right. That's exactly
- 44:25right. So if you look at the encoding
- 44:29especially for uh T1 right uh and T2 uh
- 44:34it's just one hot encoding. So it's just
- 44:36if there's a bit in that location, that
- 44:38value gets pushed up to the stack. So
- 44:40that makes the code dense in a sense
- 44:42that one instruction could move, you
- 44:44know, eight or even up to 12 values up
- 44:48uh to the stack. So that's that's
- 44:49efficient. However, it never knew what
- 44:52order you intended it to be. So that's
- 44:54what you as a programmer have to keep
- 44:56track of. My suggestion is if you pop up
- 44:59uh you know a set of n registers then
- 45:02you should or push up a set of n
- 45:04registers you should pop back exactly
- 45:05that same uh number. Don't like mix and
- 45:08match because then you're going to have
- 45:09to keep track of what order the the um
- 45:12compiler will do.
- 45:15All right. Okay. So let's go through um
- 45:20a function that will need uh some more
- 45:24uh some uh push and pops and to keep
- 45:27track of uh uh link registers when you
- 45:30do a function that calls a function. So
- 45:32here quad's going to call a function
- 45:35quad and that function is going to go
- 45:37and call square. And so now we're going
- 45:40to have to keep track of the link
- 45:41register over multiple uh nested uh
- 45:44functions.
- 45:47Okay. So we have assembly here we have
- 45:50our registers and then we have the uh
- 45:53you know the program uh memory locations
- 45:56of that assembly.
- 45:58So and then at the top we have our stack
- 46:00and remember the stack's always at the
- 46:02top of memory pointing down and usually
- 46:05our code starts at the bottom and comes
- 46:06up. All right so now the stack pointer
- 46:09is pointing up here. The value of the
- 46:11data where the stack pointer is pointing
- 46:13isn't necessarily relevant, right? um if
- 46:16that data is something we're going to
- 46:18pull out, but it's just pointing to the
- 46:19last relevant data. So in this thing
- 46:21where I just put dashes because you
- 46:23don't actually need to know what the
- 46:24value of that data is. It just happens
- 46:25to be data there. All right. And now the
- 46:28program uh counter is going to start
- 46:30here. Um it's going to move uh two into
- 46:34R0. Then we're going to branch. It's
- 46:37going to branch and update the link
- 46:39register to the address here where quad
- 46:41is. There we go.
- 46:44And then it didn't it updated the next
- 46:47instruction. So 1 4 0 is here. So when
- 46:51we return that's where we're going to
- 46:52be.
- 46:54And then uh let's see. Quad pushes for
- 46:58whatever reason. Who knows why? Uh quad
- 47:00pushes uh the link. Oh no, I do know
- 47:02why. Sorry. That quad pushes the link
- 47:04register up to the stack. Why does it do
- 47:06that? Because when quad Paul calls
- 47:08square that will override uh the link
- 47:12register and you wouldn't know it
- 47:14wouldn't know its way home. So it's got
- 47:15to go push that value up on the stack.
- 47:17Then it calls uh square that link that
- 47:21is what updates the link register here
- 47:23which would have overridden the old one.
- 47:26Then we do the multiply R0* R0. We
- 47:29branch back.
- 47:31So now the uh link register goes in the
- 47:33PC. We do it again.
- 47:37uh we squared it and then uh we're going
- 47:40to come back to quad. Now quad is going
- 47:42to pop the link register
- 47:44um front that's held in the stack and
- 47:47put it back in LR
- 47:50and then you're going to go and branch
- 47:52to the register link register in quad
- 47:55and get back to where you started.
- 47:58What questions do we have?
- 48:04Super simple, you guys. No questions. I
- 48:06can't be that good a teacher.
- 48:11>> If you're going to do a a nested uh
- 48:14function, yes, but if it's just one
- 48:15layer deep, you don't have to.
- 48:24All right.
- 48:26Uh let's see. Okay. So, that's it. Um
- 48:29we'll pass in your home. Well, we
- 48:31actually got one more slide. What do we
- 48:32got? Okay. So today we recap tools. Um I
- 48:35think the biggest thing I want you to
- 48:36remember about the tool chain is that
- 48:39there is an entire tool chain underneath
- 48:41there that you could manipulate by hand
- 48:42if you needed to. And if you're working
- 48:44at a company, it's very likely that
- 48:46you're going to be using uh somebody in
- 48:48your company's using the raw GNU radio
- 48:50or GNU uh tool chain because it gives
- 48:53you the most control when your IDE
- 48:55fails. Uh and then it's important to for
- 48:58the application binary interface to know
- 49:00how to write the functions, what those
- 49:02rules are, and how to work your way
- 49:03through those problems. All right, so
- 49:06please turn in your uh worksheets. I'll
- 49:09put these uh at the ends here so makes
- 49:11it easy to tournament.
About this transcript
This page contains the full transcript of EECS 373 - Fall 2026 - Lecture 3: Toolchain & ABI by Interactive Sensing and Computing Lab , generated from the public captions YouTube serves with the video. The transcript has 8,144 words across 1,193 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.