Help me on pop eax

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
digo_rp
Member
Member
Posts: 233
Joined: Sun Jun 05, 2005 11:00 pm

Help me on pop eax

Post by digo_rp »

guys, how many bytes push reg32 takes ? should be 4 bytes ?

example

push esp
call _isr_handler
pop eax <- I want to change to add esp, 4

is that right ?

cuz add add esp, 4 takes only 1 clock against 4 clocks of pop reg32

is that right ? when we push a reg32 " eax, esp, etc " it dec stack with 4 bytes ? then when we need to pop that reg32 is just to add esp, 4 ?

any helps are welcome.

ps. sorry for my poor english
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Yes, that is correct. I use this when I pass many things to a function as well, just add the same # of data that you pushed. An easy way to verify is to print out ESP before and after the function (and push/add esp) and make sure they are the same. For a push eax, it will be 4-bytes, so you simply add 4. If you push eax and ebx, you can add 8, etc. If you push ax, that would be 2, and al or ah is 1. Hope this helps.
urxae
Member
Member
Posts: 149
Joined: Sun Jul 30, 2006 8:16 am
Location: The Netherlands

Post by urxae »

Ready4Dis wrote:If you push ax, that would be 2, and al or ah is 1. Hope this helps.
Sorry but that is just not correct. x86 processors decrease the stack pointer at least 4 bytes per register pushed, no matter the size of the register involved. (at least, in 32-bit mode. In 16-bit mode it's at least 2 bytes IIRC. I'm not sure about 64-bit mode)
digo_rp
Member
Member
Posts: 233
Joined: Sun Jun 05, 2005 11:00 pm

tnx so much

Post by digo_rp »

tnx a lot guy
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

urxae wrote:
Ready4Dis wrote:If you push ax, that would be 2, and al or ah is 1. Hope this helps.
Sorry but that is just not correct. x86 processors decrease the stack pointer at least 4 bytes per register pushed, no matter the size of the register involved. (at least, in 32-bit mode. In 16-bit mode it's at least 2 bytes IIRC. I'm not sure about 64-bit mode)
I haven't played with it much, but are you positive, I thought that 32-bit mode, 32-bits was just the default, i'm pretty sure you can push other sizes as well, otherwise how does it handle something like this:

Test db 13

push byte [Test]
pop al

You're telling me that it pushes 4-bytes for Test and pops 4-bytes into al (basically wasting 3 byte on the push, and 3 on the pop)? I am pretty sure that is not correct, but like I said I haven't played with it much to really know, if so, let me know because i'm curious now.
nick8325
Member
Member
Posts: 200
Joined: Wed Oct 18, 2006 5:49 am

Post by nick8325 »

Ready4Dis wrote:I haven't played with it much, but are you positive, I thought that 32-bit mode, 32-bits was just the default, i'm pretty sure you can push other sizes as well, otherwise how does it handle something like this:

Test db 13

push byte [Test]
pop al

You're telling me that it pushes 4-bytes for Test and pops 4-bytes into al (basically wasting 3 byte on the push, and 3 on the pop)? I am pretty sure that is not correct, but like I said I haven't played with it much to really know, if so, let me know because i'm curious now.
There's no such instruction as pop al. According to 386intel.txt, you can push/pop 16-bit or 32-bit registers, and 8-, 16- or 32-bit immediate values (i.e. constants). But the amount of data that's pushed depends on the operand size. So

Code: Select all

Test dw 13

o16 push word [Test]
pop ax
should work, and only use 2 bytes.

EDIT: Or

Code: Select all

o16 push byte 13
pop ax
Last edited by nick8325 on Wed Jan 17, 2007 11:06 am, edited 1 time in total.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

Ready4Dis wrote:
urxae wrote:
Ready4Dis wrote:If you push ax, that would be 2, and al or ah is 1. Hope this helps.
Sorry but that is just not correct. x86 processors decrease the stack pointer at least 4 bytes per register pushed, no matter the size of the register involved. (at least, in 32-bit mode. In 16-bit mode it's at least 2 bytes IIRC. I'm not sure about 64-bit mode)
I haven't played with it much, but are you positive, I thought that 32-bit mode, 32-bits was just the default, i'm pretty sure you can push other sizes as well, otherwise how does it handle something like this:

Test db 13

push byte [Test]
pop al

You're telling me that it pushes 4-bytes for Test and pops 4-bytes into al (basically wasting 3 byte on the push, and 3 on the pop)? I am pretty sure that is not correct, but like I said I haven't played with it much to really know, if so, let me know because i'm curious now.
Yes.

IIRC you can use a size override or something to prevent that but it's strongly disrecommended because the penalty paid in speed by not aligning the stack is so much bigger than saving 2/4/6 bytes.
Tyler
Member
Member
Posts: 514
Joined: Tue Nov 07, 2006 7:37 am
Location: York, England

Post by Tyler »

Depending on the stack size set up in the GDT, the same number is always pushed and popped for that stack. If you push AL onto a 32-bit stack it pushes it on and decreases by 4 bytes. It is you responsibility to pop it into AL, therefore increasing by 4 bytes and filling AL with the correct data. If you POP AX after a PUSH AL... the top half of AX will have unknown data in which you cannot predict.
Post Reply