x86 Assembly – A crash course tutorial Ii
So this is part 1 1/2 of the tutorial since it’s real short, but I hope it will help you to get started with assembly.
Let’s review. You have the basic A-DX registers. As I mentioned before the AX register stands for Accumulator and it is used to store a number that represents a function to execute when using a system call. BX stands for base and it is mainly used as a pointer to somewhere in the program’s memory when using instructions that read from or modify memory. CX and DX may be manipulated in any way you like.
Now in the last tutorial, I showed some basic instructions to manipulate registers and stuff. But to actually do something in assembly, such as print a string, you would have to use a system call. A system call is a signal from an application to the operating system’s kernel to request a service. This is implemented through interrupts, which are declared with a byte (0x00-0xFF) to specify which service to call from the operating system. The instruction to do that in assembly is, like most other instructions, relatively easy: [u]int XX[/u] where XX is a hex digit to specify for which system call.
Now since there are only 255 interrupts to call, some interrupts allow you to specify a sub-function to use by setting the value of the AH register, followed by other byte(s) size parameters in other registers. One example of this is found in interrupt 0x21 where you access the MS-DOS API to invoke various DOS services.
Well it sounds complicated now, but here I will show you an example of calling the DOS interrupt to print a character:
mov ah,02 mov dl,41 int 21
First I placed the byte value 2 into the AH register. Which is an index to the sub-function in the DOS interrupt to print a character. When using that sub-function, the parameter for which character to print is placed in DL. In this case, I specified 0x41, which is the ascii code for the letter ‘A’. Then I performed the interrupt call to 21 (MS-DOS API interrupt) to actually execute the action.
Now you may be wondering how I know which values to put into the registers and which interrupts to call. Easy, there is documentation on the functions and sub-functions of x86 DOS based system interrupt calls located here: http://www.ctyme.com/intr/int.htm. It is an html linked page version of Ralf Brown’s Interrupt List who documented many system calls (including undocumented ones…which would make it documented already so never mind). To research with it just click on which interrupt you will call (In my case for the code above it’s number 21) and then it has a list of sub-functions for you to see what to set the AX register to and it’s parameters for the other registers.
In order for you to test this out you will need an assembler. You can either download an assembler or use the COM file assembler found in every 32-bit Windows OS called debug. The filename for debug is C:\Windows\System32\debug.exe If you don’t know how to use debug then see this article for a debug.exe tutorial written by me :mrgreen:
Now here I will demonstrate the cmd session where I open debug and use it to assemble the code to print a character:
C:\>debug -a 100 1337:0100 mov ah,02 1337:0102 mov dl,41 1337:0104 int 21 1337:0106 mov ah,4c 1337:0108 int 21 1337:010A -r cx CX 0000 :000a -n printa.com -w Writing 000A bytes -q C:\>printa.com A C:\>
Ok, so I added 2 more instructions to the code. As you know the first 3 resulted in the printing of letter ‘A’, but the next two instructions I used the sub-function 0x4C in interrupt 21 which is the function to terminate the program and exit to cmd. When using the int 21/AH=4C call, you specify the return code in AL which will set the errorlevel variable when the program exits.