Page 1 of 1
NASM assembler
Posted: Tue Dec 24, 2002 6:06 am
by Perica
..
Re:NASM Assembler!
Posted: Tue Dec 24, 2002 12:26 pm
by jrfritz
Yes you need to pop the args...but wait...you need to push 32-bit registers like eax, not ax.
Re:NASM Assembler!
Posted: Tue Dec 24, 2002 6:34 pm
by Perica
..
Re:NASM Assembler!
Posted: Tue Dec 24, 2002 7:49 pm
by Guest
Hi,
I don't think this will work, there are two ways, first you can use the leave instruction, but I never use this so you will need the intel reference manuals to learn it. The way I do it is by passing a value to the ret instruction like:
ret 4
will remove 4 bytes from the stack.
hope this helps.
Re:NASM Assembler!
Posted: Tue Dec 24, 2002 9:31 pm
by jrfritz
Here's some stack popping stuff:
MOV esp, ebp
POP eebp
Re:NASM Assembler!
Posted: Tue Dec 24, 2002 10:09 pm
by Perica
..
Re:NASM Assembler!
Posted: Tue Dec 24, 2002 10:15 pm
by jrfritz
Hmmmm...
I think I got confused somewhere... sorry about that.
Re:NASM Assembler!
Posted: Wed Dec 25, 2002 12:14 am
by Perica
..
Re:NASM Assembler!
Posted: Wed Dec 25, 2002 12:40 pm
by Cemre
The "Standart Call" specification says that, and that's what it is done in windows, you take arguments from the stack, you operate, and you return a value to eax like that:
push arg1
push arg2
call the_prog
mov [retval],eax
> and you don't do the poping here, the subprogram pops its arguments.
Re:NASM Assembler!
Posted: Wed Dec 25, 2002 1:01 pm
by Schol-R-LEA
Actually, AX (or more generally, EAX) is exactly where you want it to be; the gcc C calling convention for the x86 is to have the return value in EDX and EAX, where EAX is the general value EDX is for extended values (overflows, and doubles).
There are some pages on the web which detail the gcc argument-passing protocol;
this is a good one, but requires a postscript interpreter such as ghostview to read it. HTH.
Re:NASM Assembler!
Posted: Thu Dec 26, 2002 4:36 am
by Perica
..
Re:NASM Assembler!
Posted: Fri Dec 27, 2002 7:09 pm
by Perica
..
Re:NASM Assembler!
Posted: Fri Dec 27, 2002 10:32 pm
by Schol-R-LEA
Perica Senjak wrote:
Ok, in a function, when a register gets pushed onto the stack (To save it's value); Where do i start geting the previously pushed arguments? What i mean by this is, if i had a function like this
Code: Select all
_Add:
push bp
push ax
push bx
mov bp, sp
mov ax, [bp + 8] ;This is what i got a guestion about,
mov bx, [bp + 10] ;and this aswell!
add ax, bx
pop bx
pop ax
pop bp
ret
Alright, my question is, when the registers are pushed onto the stack, the registers are 2 bytes in size right? so i count up the registers pushed, bp, ax, bx = 6 bytes! So i start retrieving the first argument at 8 bytes (Do you understand what i'm saying?) BUT, if i was in Protected Mode; The PM (Protected Mode) Registers are double the size of the RM ones, right? So if i pushed ebp, eax, ebx onto the stack, would they take up 12 bytes? (Since they are double the size of RM Registers?) If they do take up 12 bytes, would i need to start retrieving the arguments at 14 bytes?
Given the design of the code as it is, you would actually be starting at [EBP+16] (that is 12 + 4); in p-mode, PUSH and POP always operate on a doubleword at a time. However, it is conventional to set the EBP
before pushing any other registers for saving, which would place the first argument at [EBP + 8] consistently.
There is also a bug in your code, and I am quite sorry to say I missed it earlier. By restoring AX (or, in p-mode, EAX and EBX), you are overwriting the return value in AX, so that the function has no effect other than to consume cycles and memory.
IIRC, the gcc calling convention is that EBP, ESP, EBX, EDI and ESI
must be saved and restored by the called function if they are used during the function's operation; conversely, it is assumed that EAX and EDX, which are used to return values, are trashed even if there is no return value. Other registers are assumed to be volatile; saving them is a good procatice, but not strictly, necessary, AFAICT. If anyone knows differently, please et me know.
HTH.