Okay, so I have been writing assembly language programs for a little bit now and to be honest with everyone, not like it is not obvious, assembly can be very frustrating especially when you write code and it seems to make logical sense. However, when you run the program, it either says segmentation fault, memory corruption issues, or the program displays a bunch of random text to the screen.
Okay so, recently I have been trying to write an application that does something simple using assembly. The goal was to write a program with Nasm and have it display the number of arguments passed to our program.
From my previous posts, we know that ebp+4 contains the return address after the main method is executed. We also now that ebp+8 is the first parameter passed to main, ebp+12 is the second parameter, and so on and so on with 4 added to each time. This is because from the C programming language the main method has a header declaration that is of the following syntax:
With this in mind, I set out to write a program in assembly that would simply display the number of arguments that was passed to our program to the screen. In my first run at it, I produced the following lines of code:
Now, just looking at the above code, everything appears to be in order. I moved the value stored on the stack into the accumulation register (which of course resides in the CPU, for increased performance). Then I pushed the string formater address that will display the number, and finally, I called printf from the C standard library.
The above code should should work. Actually, it does work. However, the problem I encountered was that after the call to printf, the value stored in eax register was not the same value before the call. Which means that printf method changes the content of registers.
So the take away point from this is that, if you expect the contents of a register to have the same values after a function executes then it behooves you to save those registers value onto the stack and restore them after the function all. So the above code because safe by changing it to:
Okay so, recently I have been trying to write an application that does something simple using assembly. The goal was to write a program with Nasm and have it display the number of arguments passed to our program.
From my previous posts, we know that ebp+4 contains the return address after the main method is executed. We also now that ebp+8 is the first parameter passed to main, ebp+12 is the second parameter, and so on and so on with 4 added to each time. This is because from the C programming language the main method has a header declaration that is of the following syntax:
int main(int numArg, char* actualArgContents[]])
With this in mind, I set out to write a program in assembly that would simply display the number of arguments that was passed to our program to the screen. In my first run at it, I produced the following lines of code:
;an equivalent program to this in assembly SECTION .data msg: db "Arg = %s ",10,0 msg2: db "Arg Count = %d", 10,0 SECTION .text ;allow access to printf extern printf ;make our main available externally global main main: ;int main(int numArguments, char* arg[]) push ebp mov ebp , esp sub esp, 4 mov eax, DWORD[ebp +8] ;points to numArguments mov ebx, DWORD[ebp +12] ;points to arg mov ecx , 0 ;attempt to display the number of arguments push eax ;push 4 bytes, contains number args push msg2 ;memory address are 4 bytes in size call printf add esp, 8 ;cleans up the stack;8= 2 items of 4 bytes in size mov esp, ebp pop ebp ret
Now, just looking at the above code, everything appears to be in order. I moved the value stored on the stack into the accumulation register (which of course resides in the CPU, for increased performance). Then I pushed the string formater address that will display the number, and finally, I called printf from the C standard library.
The above code should should work. Actually, it does work. However, the problem I encountered was that after the call to printf, the value stored in eax register was not the same value before the call. Which means that printf method changes the content of registers.
So the take away point from this is that, if you expect the contents of a register to have the same values after a function executes then it behooves you to save those registers value onto the stack and restore them after the function all. So the above code because safe by changing it to:
;an equivalent program to this in assembly SECTION .data msg: db "Arg = %s ",10,0 msg2: db "Arg Count = %d", 10,0 SECTION .text ;allow access to printf extern printf ;make our main available externally global main main: ;int main(int numArguments, char* arg[]) push ebp mov ebp , esp sub esp, 4 mov eax, DWORD[ebp +8] ;points to numArguments mov ebx, DWORD[ebp +12] ;points to arg mov ecx , 0 ;new pushad ;save the all the register values on the stack ; alternatively you could just do 'push eax' ;attempt to display the number of arguments push eax ;push 4 bytes, contains number args push msg2 ;memory address are 4 bytes in size call printf add esp, 8 ;cleans up the stack;8= 2 items of 4 bytes in size ;new popad ;restore all the register values on the stack ; alternatively you could just do 'pop eax' mov esp, ebp pop ebp ret
Interesting post... Wish I saw it a few days ago when I was stuck on the same issue! At least now this clears it up for me! Thanks!
ReplyDelete