I\'m writing a code that prints out the 2nd argument of a program. I understand that ebp+8
holds number of argument, ebp+12
holds address of name of pr
dword [ebp+12]
is a pointer to an array of string pointers. The first element of that array is a pointer to the first string, the second element is a pointer to the second string etc. Each pointer is 32-bits (4 bytes) wide.
To get a pointer to the second string would require getting the pointer at dword [ebp+12] + 4
. You can't do that directly in x86 addressing. You can do it by moving dword [ebp+12]
into a register like EAX, add 4 to it (since a pointer is 4 bytes wide) and then dereference that to get a pointer of the second string.
Replace:
mov eax, dword [ebp+16] ; prints 1st letter of 2nd argument
mov al, byte[eax]
call print_string
With:
mov eax, dword [ebp+12]
mov eax, [eax+4] ; EAX = pointer to 2nd argument
call print_string
This would print out the second argument. The first argument can be printed out with:
mov eax, dword [ebp+12]
mov eax, [eax] ; EAX = pointer to 1st argument
call print_string
Of course mov eax, [eax+8]
would get the 3rd argument and so on.
You can't use print_string
to print a single character in a register (like AL). EAX must be a pointer to a NUL(\0) terminated string.
Something else you can do is use scaled index addressing to step through an array (like your arguments):
mov ebx, dword [ebp+12]
xor esi, esi ; Index of first argument (index=0)
mov eax, [ebx+esi*4] ; EAX = pointer to 1st argument
call print_string
inc esi ; Next argument (index=1)
mov eax, [ebx+esi*4] ; EAX = pointer to 2nd argument
call print_string
inc esi ; Next argument (index=2)
mov eax, [ebx+esi*4] ; EAX = pointer to 3rd argument
call print_string
With this idea you can probably see how you can create a loop that goes through the arguments. I leave that as an exercise for the reader. This is another handy quick reference for addressing modes.