NASM assembler

Programming, for all ages and all languages.
Post Reply
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

NASM assembler

Post by Perica »

..
Last edited by Perica on Fri Dec 01, 2006 6:47 pm, edited 3 times in total.
jrfritz

Re:NASM Assembler!

Post by jrfritz »

Yes you need to pop the args...but wait...you need to push 32-bit registers like eax, not ax.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:NASM Assembler!

Post by Perica »

..
Last edited by Perica on Fri Dec 01, 2006 6:47 pm, edited 1 time in total.
Guest

Re:NASM Assembler!

Post 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.
jrfritz

Re:NASM Assembler!

Post by jrfritz »

Here's some stack popping stuff:

MOV esp, ebp
POP eebp
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:NASM Assembler!

Post by Perica »

..
Last edited by Perica on Fri Dec 01, 2006 6:48 pm, edited 1 time in total.
jrfritz

Re:NASM Assembler!

Post by jrfritz »

Hmmmm...

I think I got confused somewhere... sorry about that.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:NASM Assembler!

Post by Perica »

..
Last edited by Perica on Fri Dec 01, 2006 6:48 pm, edited 1 time in total.
Cemre

Re:NASM Assembler!

Post 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.
Schol-R-LEA

Re:NASM Assembler!

Post 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.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:NASM Assembler!

Post by Perica »

..
Last edited by Perica on Fri Dec 01, 2006 6:48 pm, edited 1 time in total.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:NASM Assembler!

Post by Perica »

..
Last edited by Perica on Fri Dec 01, 2006 6:48 pm, edited 1 time in total.
Schol-R-LEA

Re:NASM Assembler!

Post 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.
Post Reply