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
Help me on pop eax
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.
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)Ready4Dis wrote:If you push ax, that would be 2, and al or ah is 1. Hope this helps.
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:urxae wrote: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)Ready4Dis wrote:If you push ax, that would be 2, and al or ah is 1. Hope this helps.
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. SoReady4Dis 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.
Code: Select all
Test dw 13
o16 push word [Test]
pop ax
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.
Yes.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:urxae wrote: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)Ready4Dis wrote:If you push ax, that would be 2, and al or ah is 1. Hope this helps.
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.
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.
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.