Real Geeks Assemble: Beginner Assembly Part 1

Beginner Assembly Language for PPC Darwin (oh, and Mac OS X too ; – ) copyright 2003 by Terrance Gene Davis

Real geeks assemble.

This is a beginner’s guide to programming using assembly language. It is aimed at users of Darwin for PPCs. That includes users of Mac OS X. Some knowledge of C would help too. Way back in the days of the Apple ][ (for those who were out of diapers) there were many books on low level programming of the Apple. They spanned Disk Operating Systems, Hex (yes, actual hex) programming and a whole host of other low level things that real geeks like to freak out their friends and neighbors by talking about. This was the golden age, when C programmers were considered wimps. It was a great time. The books back then were written by enthusiasts for enthusiasts. They were chalk full of jokes (cryptic jokes true), they were fun to read, and had cool examples. Like how to have a disk announce it belongs to you when you boot from it. I don’t think we can bring that back, but here’s a little relic. Your first assembly program First you need a command line. In Darwin you’ve already found it. If you’re using one of those silly GUI interfaces like OS X, find the App called Terminal. Second you need a command line compiler called GNU gcc (or cc by close friends, and we’re close friends). If you type ‘cc’ at the command prompt, and it tells you that you don’t have it, you need to get it. You’re a real geek if you even care, so go find it and install it. Open pico, emacs, project builder or any other editor and type in this program.


  .globl _main
  _main:
            li r3, 13
            blr
  

Save it as plain text with the name ‘assem.S’ or ‘assem.s’ if you prefer. Watch out, some of those fancy GUI word processors throw all kinds of junk in the file you didn’t want, so you might be best off using pico. Finally compile it from the command line using the command ‘cc assem.S -o run_me’. You’ve just told our friend cc to compile assem.s into the tool run_me. You’re ready to run. Is your heart pumpin’? It should be. If you typed the program in wrong it will crash your computer and erase everything on your hard drive. Okay the hard drive bit isn’t likely. Now type, ‘./run_me’. Wasn’t that great? Can’t wait to show all your friends, can you! Uh, … I heard that! You said, “But it didn’t do anything….” Sure it did, and I’ll tell you what you’ve done. I’ll describe this in terms familiar too those who know high-level languages like C. 1) You started by saying “I have a global function called main.” (.globl _main) 2) Next you define main’s implementation. (_main: blah, blah, blah ….) 3) The first command is “load IMMEDIATELY 13 (into register #3)!” (li r3, l3) 4) The last command is to return. What is returned? What ever is in register #3. (blr)   Notice that like in c and java you have the starting method/function named “main”. This is no accident. If you change its name to “_joeTheFunction” our friend cc will complain. It only knows how to start with _main when we compile with ‘cc assem.S -o run_me’. There is a way to make _start the beginning function, but I’m not going to get into that here. Notice that like in c and java you have the starting method/function named “main”. This is no accident. If you change its name to “_joeTheFunction” our friend cc will complain. It only knows how to start with _main when we compile with ‘cc assem.S -o run_me’. There is a way to make _start the beginning function, but I’m not going to get into that here. You’ve probably noticed that I refer to the function name with and without the leading “_”. The “_” needs to start the function name in assembly, but it corresponds to the c function name that is identical, minus the leading underscore. Proof Now I know that there is always a bunch of skeptics out there who say show me some proof. So here is your second program. It is in two pieces. The first piece is a VERY simple c source file, and the second is a slightly modified version of the program we just ran. Here’s source file number one. Save it as ‘main.c’.


  #include <stdio.h>

  int main() {
        printf("%dn", assemblyFunction());

        return 0;
  }
  

Here’s source file number two. Save it as ‘assem.S’.


  .globl _assemblyFunction

  _assemblyFunction:
            li r3, 13
            blr
  

Compile it from the command line using the command ‘cc main.c assem.S -o run_me’. And once again, run it with ‘./run_me’. There you go. You have just printed a perfectly healthy “13”. Haven’t you always wanted one of your own. You don’t have to share with your friends if you don’t want to. Now the really cool part is that you called the function assemblyFunction() in your c function main(), and the code from your assembly program did the work of coming up with a “13”. Notice the leading underscore appears in the assembly version of the function name. Just get use to this. Stick around. The next chapter has our “hello world” example. Assignments 1) Modify the second example in this chapter to use the function callMe(). 2) Modify the second example to load 44 into register r3. 3) Create a mixed c and assembly program (two source files) that uses two functions, callMeFirst() and callMeSecond() to print out two different numbers.