I have this C code portion:
#include <stdio.h>
void main()
{
int n, array[1000], c, d, t, e;
char step;
puts("Enter a number\n");
scanf("%d", &n);
puts("any help? [y/n]");
scanf(" %c",&step);
puts("Enter integers\n");
}
the corresponding assembly code of mine:
push prompt1
call _printf
add esp, 4 ;print and add 4 bytes to esp
push num
push sc1
call _scanf
add esp, 8 ;scan and add 8 bytes to esp
section .data
prompt1 db "Enter a number",13,10,0
sc2 db " %c",0 ;other constants
And the resulting assembly code after converting the C file to NASM format in command prompt.
mov dword [esp], ?_001 ;?_001 is prompt1
call _puts
lea eax, [esp+0FBCH]
mov dword [esp+4H], eax
mov dword [esp], ?_002 ;?_002 is sc1
call _scanf
mov dword [esp], ?_003
call _puts
full assembly code: http://pastebin.com/R6UHRw8x However,I did not understand the converted assembly code because mov dword [esp+4H], eax uses [esp + 4] and the next line uses only [esp]. Shouldn't it be [esp] first then [esp + 4]? I don't understand and I saw many occurrences of it in the file. Besides push and mov, how is the generated code different from mine regarding esp?
The compiler output passes scanf pointers to stack space, instead of to static storage.
It lets args build up on the stack instead of popping after every call (so it can use mov). Neither way avoids inserting stack-engine synchronization uops, unfortunately.
According to the ABI/calling convention, the first arg (in C order) is at the lowest address, just above the return address. So it's correct to put esp+0FBCH into [esp+0x4], and the format-string pointer into [esp]. See the x86 tag wiki for links.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With