Page 1 of 1
Problems accessing the stack.
Posted: Sat Mar 13, 2004 12:34 am
by Neptune
I seem to be accessing the stack incorrectly here. Basically, what I am trying to do is load the address of a null-terminated string that was passed onto the stack into edx, loop through and print each character. For some reason, I cannot get it to work. Here is the call:
Code: Select all
entry:
push msg
call print
add esp, 0x04
xor eax, eax
ret
And here is the function:
Code: Select all
print:
push ebx ; preserve, C-style
lea edx, [esp+8]
printloop:
mov al, byte [edx]
or al, al
jz endprint
mov ah, 0x0e ; BIOS print-char subservice
mov bx, 0x0007 ; text attribute
int 0x10 ; BIOS video service
inc edx
jmp printloop
endprint:
pop ebx
ret
Re:Problems accessing the stack.
Posted: Sat Mar 13, 2004 5:41 am
by Tim
You need MOV, not LEA. Currently you are printing the contents of the stack. You want to print the contents of a string, a pointer to which is on the stack.
Re:Problems accessing the stack.
Posted: Sat Mar 13, 2004 12:43 pm
by Neptune
OK, but the syntax would be the same - correct? ie:
mov edx, [esp+8]
Re:Problems accessing the stack.
Posted: Sat Mar 13, 2004 1:00 pm
by Candy
sebastian wrote:
OK, but the syntax would be the same - correct? ie:
mov edx, [esp+8]
in theory, yes
In practice, it should be
mov edx, [esp+4]
because you want the msg.
Re:Problems accessing the stack.
Posted: Sat Mar 13, 2004 2:26 pm
by Neptune
I guess the real problem is just that I do not know how to access data from the stack properly. I simplified the program a bit in order to narrow down the possibilities, but the output is still erroneous.
(assembler: nasm, 32 bit environment)
entry:
push msg
call print
add esp, 4
ret
print:
lea edx, [esp+8]
push edx
call _printf
add esp, 4
ret
I even changed 'lea' to 'mov', but that didn't work either. Can someone show me a working example of using the stack to pass strings?
Re:Problems accessing the stack.
Posted: Sat Mar 13, 2004 2:35 pm
by Candy
Code: Select all
entry:
push msg
call print
add esp, 4
ret
print:
mov edx, [esp+4]
push 0
push edx
call _printf
add esp, 8
ret
ps: are you sure you want to ret? there's nothing to catch you, probably...
Re:Problems accessing the stack.
Posted: Sat Mar 13, 2004 5:05 pm
by Neptune
Thanks a million, Candy! I've been toiling with that for several days now - whew!
One more question:
>> mov edx, [esp+4]
I thought that when using 'call', the return address is pushed onto the stack, so that upon function entry esp+4 would contain the return address and the parameter I passed would be at esp+8?
Re:Problems accessing the stack.
Posted: Sat Mar 13, 2004 5:20 pm
by Neptune
>> are you sure you want to ret? there's nothing to catch you, probably...
What do you mean? I thought you always has to ret (from 'main', to the OS, and from frunctions, to the caller)?
Re:Problems accessing the stack.
Posted: Sun Mar 14, 2004 12:57 am
by Candy
sebastian wrote:
>> mov edx, [esp+4]
I thought that when using 'call', the return address is pushed onto the stack, so that upon function entry esp+4 would contain the return address and the parameter I passed would be at esp+8?
It is on the stack, but the stack pointer points to the last thing you put on it. So, [esp] would be the return address, and [esp+4] is the address of the first variable. When you push something on in your routine (say, the old base pointer) [esp] would be the base pointer, [esp+4] would be the return address and [esp+8] would be the first argument.
For completeness (if you're using 32-bit linux systems, you can ignore it):
In windows parameters are passed by __stdcall. IIRC, that meant that the LAST parameter is [esp+8] after pushing the base pointer.
On any non-32-bit system the parameters are not 4 bytes. On any system they're [?sp + n] where ?sp is the name of the current stack pointer (sp, esp, rsp) and n is the number of bytes that hold those amounts of bits (2, 4,
.
64-bit arguments on a 32-bit system (and so on for the 16-bit systems etc.) are passed in 2 arguments rather than one. Count those doubles too. They're passed in little-endian order, so the first n-byte word is the smaller half, and the last one is the larger half.
>> are you sure you want to ret? there's nothing to catch you, probably...
What do you mean? I thought you always has to ret (from 'main', to the OS, and from frunctions, to the caller)?
Sorry, wrong forum. Thought you were doing osdev (barely any ASM programming otherwise) and if you were, there's no OS below you. That's why I said that.
Re:Problems accessing the stack.
Posted: Sun Mar 14, 2004 3:45 am
by Neptune
Ah, ok, I think I've got it now.
>> Thought you were doing osdev
I am, actually, just thought you were referring to normal assembly - funny. ;D
For now I'm just jumping to the BIOS reboot routine at 0xffff:0000 at the end of 'main'.
Anyway, thank you for clearing that up for me - I was really stuck!
Cheers.