Assembly 在堆栈上推送一个字节(IA32)

Assembly 在堆栈上推送一个字节(IA32),assembly,x86,Assembly,X86,我的课本上有一个问题: 根据操作数给出正确的后缀: push $0xFF 答案是: pushl $0xFF 但是为什么不pushb$0xFF(我认为pushb不存在)或者pushw$0xFF(pushw确实存在),既然0xFF是一个字节,为什么它必须是'l',即32位/4字节?AT&t语法中push的默认操作数大小(在所有其他汇编程序中,如NASM和MASM)是当前模式的宽度(16位模式下为16位,32位模式下为32位,64位模式下为64位)。这与调用/ret的“堆栈宽度”匹配 pop的默

我的课本上有一个问题: 根据操作数给出正确的后缀:

push $0xFF
答案是:

pushl $0xFF
但是为什么不
pushb$0xFF
(我认为
pushb
不存在)或者
pushw$0xFF
pushw
确实存在),既然
0xFF
是一个字节,为什么它必须是'l',即32位/4字节?

AT&t语法中
push
的默认操作数大小(在所有其他汇编程序中,如NASM和MASM)是当前模式的宽度(16位模式下为16位,32位模式下为32位,64位模式下为64位)。这与
调用
/
ret
的“堆栈宽度”匹配

pop
的默认版本也是不需要额外机器代码前缀进行编码的版本

当存在歧义时,大多数指令需要显式的操作数大小,例如,
mov$1234567,(%esp)
无效,但
mov%eax,(%esp)
合法,因为寄存器暗示操作数大小

但是
push
-如果有趣,立即执行:很少使用
push
的非默认宽度,因此asm语法设计者选择为其提供默认宽度,而不需要
push$0xff
(AT&T)或
push dword 0xff
(NASM)。请注意,英特尔语法排在第一位,AT&T紧随其后。因此,AT&T语法设计者可能遵循了早期英特尔语法汇编程序的惯例

我指出这一点是因为AT&T的大小后缀语法只增加了1个字母,但英特尔的语法看起来更笨拙

push
-immediate在传统的低效调用约定中被大量使用,这些约定总是在堆栈上传递参数,因此易于键入是有意义的


你的课本上真的说了“推一个字节”,还是你编造的

正如您所说,x86中不能只推一个字节


您的汇编程序甚至无法使用编码,因为
0x000000FF
不适合符号扩展的8位整数。只能使用-128(0xFFFF80)到127(0x0000007F)之间的值适合有符号8位整数。

从这个问题上看,参数的大小并不明显。因此,从技术上讲,它也可能是16位推送(x86支持此功能)。也许他们更喜欢32位对齐方式。谢谢你的回答,那么pushw$0x08或pushb$0x08在IA32中是否有效?@amjad:不,
pushb
不存在。请参阅我答案的最后一部分,和/或链接的问题,哪些操作数大小可用。@amjad:或者你可以在桌面上试用它:
cat>foo.S
/
pushb$0x8
并运行
gcc-c foo.S&&objdump-drwC foo.o
以查看错误消息,或者在汇编时查看反汇编。或者联机执行:。但是编译器资源管理器asm源代码模式不显示机器代码:/