Editor’s Note: This article is designed to get you thinking a bit about assembly on i386 machines, and to provide an example of x86 convention function calling. Its not really comprehensive enough to serve as a thorough tutorial. Look here, or here for a bit more comprehensive introduction.

Tinkering with assembly code is a great way to learn about how code compiles and runs, and provides great insight into writing better code. Its probably easier and [frankly] more useful, to insert some carefully crafted assembly code into a C program at just the right place. However, you learn more about the machine, and the way your code is stitched together if you call some C code from an assembly program, which is what we’ll do here.

Let’s think a bit about what we need to do to mix C code into assembly. As you probably already know, when you compile a C program, the compiler produces binary code that you can run on the CPU. When you assemble an assembly program, the assembler makes the same type of binary code as well. You can pretty easily mix these two types of code to create a coherent program that you can run. Doing this type of stuff is useful for making highly optimized code, dealing with embedded devices, writing device drivers, or developing low-level things in general. Here, we’re just doing it to tinker. :)

Now, here’s the basic thing we’re going to do here:

  1. 1. Write some C code that does something useful. I chose to do a simple calculation of the fibonacci sequence.
  2. 2. Write some assembly code that calls the C code we wrote.
  3. 3. Use a compiler to make binary code from the C code.
  4. 4. Use an assembler to make binary code from the assembly code
  5. 5. Use a linker to to stitch these two chunks of binary code together into an executable.
  6. 6. Run the executable!

The C code is pretty straightforward.

//filename: fib.c
int fib_linear(int fib_num) {
    int i,a,b,tmp;
    tmp=1;
    a = 1;
    b = 1;
    for(i=0; i< fib_num-1; i++)
    {
        tmp = a+b;
        a=b;
        b=tmp;
    }
    return b;
}

I’ve only used 3 instructions, mov, push, and call. mov simply puts an integer value into a register. push simply puts a value in a register onto the stack, a special bit of memory each program needs. call changes the flow of execution, by calling a function. (In case you forgot, assembly code pretty much shuffles data between <a href=”http://en.wikipedia.org/wiki/Hardware_register”>registers.</a> x86 has (essentially) 4 registers most people use for data, called EAX, EBX, ECX, and EDX.)

The last question here is “how do we call a function from an assembly file?” By the convention used for all x86 code, the result of the function is returned in the EAX register. According to convention, the function is free to trash EAX, ECX, and EDX, but not EBX. It is common to allow some registers to be trashed (caller-save registers) and some not to be trashed (caller-save) in all architectures. This allows for greater interoperability between code. In order to call the function, we need to load in the arguments to the function, then call the function. So if you want to call foo(x,y,z), you’d push z, push y, push x, then call foo. When the function finishes, look for the result in EAX. Don’t count on EAX, ECX, and EDX to be unchanged after the function call. Its just that simple.

So, here’s the actual assembly code you can look at!

;filename: main.as
extern fib_linear ;extern notifies the assembler that this label exists outside the file
extern printf
 
section .data
        msg:    db "eax=%X   ebx=%X   ecx=%X   edx=%X", 10 ;just a string for printf to use
section .text
        global main
 
main:
        mov ebx, 9   ;we will be computing the 9th fib number
        mov eax, 0xbeef ;random values
        mov ecx, 0xdead
        mov edx, 0xface
 
        push edx     ;load in 5th arg
        push ecx     ; 4th arg
        push ebx     ; 3rd arg
        push eax     ; 2nd arg
        push msg     ; 1st arg
        call printf ;same as calling "printf("eax= ...", eax, ebx, ecx, edx);"
 
        push ebx ;load in 1st argument
        call fib_linear ;calls "fib_linear(eax)"
 
        push edx
        push ecx
        push ebx
        push eax
        push msg
        call printf     ;print out the values of the 4 registers
 
        mov eax, 1      ;stops the program the right way
        mov ebx, 0
        int 80h

To test this out, simply run the commands:

nasm -f elf -o main.o main.asm  #assemble our asm file
gcc fib.c main.o -o fib_asm     #compile and link in one step
./fib_asm                       #run the program you'll see the value of the registers before and after the call

There you go! You’ve just made your first hybrid x86 assembly/C code program! I hope I’ve got you interested in assembly a bit through this short crash article. If you want a full tutorial you can look here, or just google around a bit. Happy hacking!

How To Make A Kernel Sandbox using QEMU

January 9th, 2010 by Kevin

Last post, I described a few reasons why a kernel sandbox might boost your ability to tinker with the kernel. Now I’m going to describe how you can do this!

I use a debian virtual disk image, along with QEMU for the virtualization. Why QEMU? Its open source (always a plus), free, and has been used pseudo-extensively by a lot of kernel developers. Furthermore, its controlled by the command line, which makes it easier for the type of development we’re doing.

First, we have to make the virtual machine’s system disk image by allocating a hunk of disk space in a big amorphous file. You can do this easily using the tool, “dd”. Here I am making a garbage file that is 1 GB (1M * 1M) in size. Make sure you have the space available! We will later fill this with useful data.
dd if=/dev/zero of=vm_disk.img bs=1M count=1024
Now that we have a big garbage file to work with, we have to format it with a filesystem. Set up the ext3 filesystem on the image by doing:
mkfs.ext3 vm_disk.img
(if prompted, hit ‘y’)

Mount the image in your filesystem, so you can poke around in your file:
mkdir /media/vm
mount -o loop vm_disk.img /media/vm

Now we have a file on your computer that is, for all intents and purposes, an empty virtual hard drive. We have to fill it with a minimal system now. Debian has a pretty easy tool that does just this. By running:
debootstrap sid mounted/ http://ftp.us.debian.org/debian/
Your computer will put a basic stable debian installation on your virtual disk image. Your Virtual Disk is now ready for use! Let’s unmount it…
umount /media/vm

Now, its up to you to make the latest awesome change to the kernel source, configure, and compile it. Doing this is beyond the scope of this article, but if you’re reading this article, there’s a pretty good chance you’re already schooled in how to do all this. :). As you know, when you’re done with this step, you have a kernel disk image as a result.

Alright, now we’re ready to finally run the kernel you built on the virtual disk you made! Assuming you’ve installed QEMU using your system’s package manager, just run:
qemu -hda vm_disk.img -kernel kernel_source/arch/x86/boot/bzImage -append "root=/dev/sda"

You’ll see the system booting up [hopefully], and you’ll be able to see how great the changes you made to the kernel are (or aren’t :-) ).

A few warnings: Make sure you have ext3 support compiled /into/ the kernel. You can use these techniques to do a few more advanced features, like rolling a swap file, and using that in qemu. Read qemu’s manpages to think up things to do. I just listed a few of the warnings that came from the top of my head, if you think of any more, be sure to leave them in the comments!

I hope that this suggestion helps you in your hacking!

Kernel Sandbox

January 8th, 2010 by Kevin

This article is about a suggestion for making kernel work easier. The next article will be about how to implement the suggestions I make.

Kernel coding is a bit of a pain, if you compare it to userspace coding. You loose a lot of nice things in userspace, like segfaults (think you can’t live with them? try living without them ;) ), and a bad kernel build can easily stop a system cold. These stupid little annoyances can really stop beginners from getting involved! Figuring out how to work around this took me longer than I had hoped, and I’m going to share some of the things that made kernel work go from an omg-pain-in-the-arse to only marginally more painful than userspace coding :)

Firstly, I’ve really taken a shine to working in a nice VM sandbox environment for a few reasons:

  • Stupendously bone-headed kernel hacking can do funny things to your computer, including bricking it, turning off some part somewhere, and having to wade through documentation to figure out what is going on, or simply causing a system crash.
  • Rebooting into a new kernel each time is very annoying. When coding in the kernel (especially if you’re just tinkering with things in the core like I’ve been doing lately), you need to boot into that kernel to test your changes. Waiting the 30 seconds is pretty annoying, and then, all your programs and documentation you had up all have to be re-started. If this sounds like pointless whining, just try spending 40% of the time you are working on rebooting, restoring, and waiting for the machine to do its thing.
  • Kernel panics are the worst. These are simply caused when something very wrong happens in the kernel. The infamous blue screen of death is the result of a Windows kernel panic. This being said, if you’re developing or tinkering with a kernel, there’s a mild chance that you’re gonna cause a kernel panic at some point or the other. If you’re testing on a real machine, a kernel panic will lock your computer up, you’ll lose work you’ve been doing, etc.


  • How can we avoid these three barriers to kernel coding? Easy. Boot the kernel up in a virtual machine, like qemu. The virtual machine stops you from messing up your physical machine with a (potentially) wonky kernel. Furthermore, if the kernel panics in the virtual machine, you can easily shut it down, and preserve all the programs and documentation you’re using. If you do run into a panic or crash, the virtual disk image is still there after you power the virtual machine down, allowing you to view any crash logs without booting the system again. Finally, when you have to boot into a new kernel, you don’t have to kill all your programs you’re using to get the new build going.

    Hazard!Now, for the warnings! As with most things, there are trade-offs. Working in a sandbox kernel environment under a VM is nice for most of the reasons stated above. However, if you’re doing things like device driver development, its often very inadequate to just work in a VM. No matter what development you’re doing, the eventual end-game for your work is to be deployed on a real machine. You don’t want some flawless latest-and-greatest code you’ve written to work perfectly in QEMU, and panic ‘n crash on a real machine!

    All in all, simply working with a virtual machine 80% of the time is a lot nicer than working with a physical machine 100% of the time, and has really allowed me to not exhaust my patience when working with kernel code.

    Next article (published tomorrow) will be a brief how-to for how I set up a kernel sandbox.

    Back!

    December 29th, 2009 by Kevin

    If you’ve been wondering where I’ve been the last few months, the short answer is simply “here”:


    View Larger Map

    (also known as my school’s Electrical Engineering Building)

    I was working on my Senior Design Project, which was to implement an out-of-order Alpha processor using the Verilog Hardware Description Language. Put simply, me and my 3 team members made a 200MHz processor with roughly the Pentium 4 architecture for our senior design project/thesis. The class is known as a trial-by-fire introduction to hardware description languages, and we came through with good grades (and the fastest clock period in the class).

    Point is, I haven’t had a lot of free time to blog lately. :P Thankfully though, I’m on (my last undergrad) semester break and have some time to catch up on blogging, and email, job hunting, hacking, and life, so expect some useful posts soon!

    Customize the appearance of each text file you edit with vim!

    vim logoIt comes in handy to have different filetypes appear differently in your text editor. Perhaps you want tabs turned into spaces automatically in all C files, but you don’t want that to happen in Makefiles, where the tab character is necessary. Perhaps you like to do python coding with a black foreground, and write a text file with a white foreground. Maybe you want html code to have 100 characters per line but have a text file wrap at 80 characters. You get the idea.

    Filetype detection is actually not very hard to do with Vim, even though the documentation might you scratching your head about how to do it. Luckily, I’m here to explain it via examples. :)

    First of all, make sure these two lines are anywhere in your vimrc:

    filetype on
    filetype plugin on

    This will turn on the filetype detection.

    Second of all, create the directory ~/.vimrc/ftplugin

    In that directory, add the file, [file-type-name].vim where [file-type-name] is the name of the filetype you are customizing. For instance, the customization for C files would be c.vim; python files, python.vim, etc. In Ubuntu 9.04, you can find a list of supported filetypes in /usr/share/vim/vim72/ftplugin.

    In the file you just created, add the customization options what you want. When you open a new file, Vim will automatically detect the filetype (its pretty good at this) and apply the settings you specified. Use ’setl’ instead of ’set’ so the customizations only apply to the correct file. For example, here is my file for C text files.
    custom C settings file, c.vim

    " File: ~/.vim/ftplugin/c.vim
     
    color default     "use the default colorscheme
    setl textwidth=80   "80 character lines
    setl nowrap           "don't wrap lines at the end
    setl cindent           "use C style indents
    setl sw=4        "Use 4 space tabs

    See, simple as that. You’ll need a different file for each filetype you want custom settings for. Now you know how to have each filetype do its own thing!

    Shatner of the Mount

    September 23rd, 2009 by Kevin

    “Picard v. Kirk” is a classic Holy War, and really part of geek heritage. I’m not gonna declare my allegiance here, just to keep this important new piece of evidence as pure as possible.

    Here it is for your evaluation:

    Apparently it is a remix taken from an interview with William Shatner as an “Extra Feature” on a Star Trek Movie DVD.

    Posted in Random | 1 Comment »

    Google maps is a pretty good distraction during intolerable lectures. Here’s a little nugget I found today.

    I guess all those I <3 NY shirts are justified now, eh? One day I'll have to make it out there to see for myself...
    (and yes, I had to crop/edit the picture to fit on my blog. You can see for yourself if you really don’t believe me…

    Posted in Random | 1 Comment »

    New Stock Ticker for XFCE Panel!

    September 4th, 2009 by Kevin

    Stock ticker photo Back in the day, Gnome had a stock ticker panel applet that I really liked. Just a regular ticker, scrolling across the top of the screen, like you’d see on a financial news channel. Then, (according to some Gnome devs I talked to), the maintainer dropped off the face of the earth, and the applet was removed from the Gnome distribution, much to my dismay. I’ve missed it ever since.

    These days, I use xfce more than I use gnome, and I decided to write a stock ticker applet like the one that was removed from Gnome a couple years ago.

    Here it is in action:

    Planet users: click here to see it
    And, a closeup screenshot:
    Ticker

    Its implemented in C, and uses libcurl to access the Yahoo! Finance API, and uses Clutter to perform the animation. It requires an active internet connection (of course) in order to retrieve the data. All in all, I really liked the mechanisms Xfce provides for implementing panel plugins, especially when compared to gnome-panel. The plugin is [of course] licensed under the GPL. It is only to be used as a rough estimate of what the price is. Price accuracy is not guaranteed in any way. If any artist out there has some open-source financial icons to donate to the project, make sure to hit me up.

    So, if you use Xfce and are interested in the stock ticker applet, grab the source from here for now. I’ll be putting it up on the xfce-goodies svn soon, once I get my account there working.

    Its still “pretty alpha”, meaning I just got it working, but I plan on improving it to the point that its easily usable, and packaging it into a deb so that people can install it easily. There are also a few things I still want to add, like adjustable width of the plugin and selecting which way the text scrolls, but those should be coming down the pipes soon. Buy low, sell high, and enjoy my ticker program. :D

    I’ve been looking to set up a microprocessor/robotics type hobbyist lab for a while, and I’d like to use Linux as much as possible for the tools I’ll be buying and using. One of the most critical components in any good logic lab is a decent logic analyzer. A logic analyzer is a tool with multiple probes that you attach to various points to monitor the voltage levels at the test points. It’s pretty much essential if you want to figure out why your digital circuit isn’t working the right way.


    High-end logic analyzers can process data on the GHz level, and cost thousands and thousands of dollars. Luckily, companies have come out with logic analyzers that are a lot cheaper, and work well for pretty much any hobbyist or robotics project you want to do. These cheaper devices typically hook up to USB on computer, and need a program on a computer to run. Saleae released a 8 channel, 24Mhz USB Logic Analyzer for $150 a while ago, along with a Windows program to run it. They promised that equal support for Mac and Linux was coming down the tubes, and I’m happy that they are delivering. The SDK came out a while ago, and they just released an initial program, that only still lacks a few [albeit critical] features that are coming out in the next release, like working pattern triggering.

    Here’s a screenshot of the program in action (get the alpha program here):
    logic analyzer software for linux
    As you can see if you look closely, its just a simulation ( I don’t have the device yet ), but it looks like it has everything I would want out of a $150 logic analyzer. Also, the guys at Sparkfun seem to like it enough to sell it, another good mark in my book. I’ll be buying a device from here soon! Thanks for the Linux support Salhttp://www.saleae.com/logic/eae. :-)

    Fortune Cookie Signature for Thunderbird

    July 16th, 2009 by Kevin

    Credit: http://oygirl.files.wordpress.comI’ve been using Thunderbird to take care of my emails lately, I’ve found I like using a mail client with IMAP slightly better than logging onto web mail interfaces. As such, I’ve been customizing Thunderbird to be exactly what I like it to be. I decided I wanted my signature to be my name, email address, and a different saying each time.

    Here’s how I customized my signature in Thunderbird to auto-rotate fortunes.

    First of all, I wrote a short script:

    #!/bin/sh
    NAME="<big>Kevin DuBois</big>"
    EMAIL="kdub432@gmail.com"
    FORTUNE="<small><em>"`/usr/games/fortune -n 80 -s`"</em></small>"
    echo <html><body>"${NAME}${EMAIL}${FORTUNE}"</body></html> > /home/kdub/docs/signature.html

    This script creates the signature I wanted whenever its run, with a different 80 character or shorter fortune attached to the end. I used the classic program “fortune” (included by default on most distributions) to generate the fortune. They’re all pretty creative fortunes, of equal or higher quality than you’d find in a fortune cookie. :P

    Next, to make this rotate fortunes, I added this script to crontab…
    Run

     crontab -e

    next, add

     */5 * * * * /home/kdub/source/scripts/fortune.sh

    Note:For both this, and the script, adjust pathnames accordingly to where you want the signature file to live, and where you want the script to live. As you see, I keep my signature file in ~/docs and my script in the directory I keep my scripts.

    Finally, navigate to “Account Settings” in Thunderbird’s menus, and add the html file the script generates as your signature. See screenshot for where this is done. (Click to enlarge) Email Screenshot

    With this, every time you write a new email, you’ll have a new fortune to send, auto-provided for you!

    Side note: Be careful if you’ve installed the “offensive fortunes pack”. (Debian package ‘fortunes-off’).

    « Previous Entries