Assembly 在x86中将struct类型的内容推送到堆栈上
假设我声明了这样一个结构:Assembly 在x86中将struct类型的内容推送到堆栈上,assembly,x86,stack,fasm,Assembly,X86,Stack,Fasm,假设我声明了这样一个结构: struct VEC x dd ? y dd ? ends 然后我将一些数据声明为struct: section '.data' data readable writeable vec1 VEC 5,4 vec2 VEC 3,2 现在,我希望将内存位置vec1和vec2的内容推送到堆栈中。我是这样做的: push sizeof.VEC [vec1]
struct VEC
x dd ?
y dd ?
ends
然后我将一些数据声明为struct:
section '.data' data readable writeable
vec1 VEC 5,4
vec2 VEC 3,2
现在,我希望将内存位置vec1和vec2的内容推送到堆栈中。我是这样做的:
push sizeof.VEC [vec1]
push sizeof.VEC [vec2]
这不能编译。返回的错误为:
错误:未指定操作数大小。
我想知道是否有办法将此结构类型的内容放入堆栈。或者这在x86中首先是非法的
我是在Windows10上使用1.71.49版平面汇编程序编译的
一般来说,我的问题是如何让汇编器以正确的操作数大小编码一个push[mem]这只是一个如何让汇编器以正确的操作数大小编码一个push[mem]的问题。16位和64位
push
es可在64位模式下编码,但不能在32位push
es模式下编码REX.W=0将某些故障作为非法指令推送,这与英特尔insn ref手册声称操作数大小可能会被66H或REX.W覆盖的说法相反:
操作数大小。当前代码段描述符中的D标志确定默认操作数大小;可能
被指令前缀(66H或REX.W)覆盖。
操作数大小(16、32或64位)决定堆栈指针的递减量(2、4)
或(8)
注意,这是记录32位和64位模式。32位推送当然在32位模式下可用。(wiki提供手册链接)
由于有许多结构大小不能用一条指令推送,因此不可能有任何语法根据结构大小选择字、dword或qword操作数大小。不过,如果您真的愿意,您可以自己使用宏来完成
push
ing大型结构不是正常的调用约定的工作方式,所以这是它没有语法糖分的另一个原因。通常,太大而无法放入寄存器的对象是通过引用传递的。较小的对象可以通过值传递。因此您不能仅仅参数化推送的操作数大小来生成灵活的代码;根据结构的大小,您需要使用宏发出不同的指令来传递值和传递引用
由于您的结构是64位的,因此您只能在64位模式下用一条指令推送整个结构:
push qword [vec1]
push qword [vec2]
(或者如果FASM使用MASM语法而不是NASM,则为qword ptr
。这只是一个如何让汇编程序以正确的操作数大小对push[mem]
进行编码的问题。16位和64位push
es可在64位模式下编码,但不能在32位push
es模式下编码REX.W=0将某些故障作为非法指令推送,这与英特尔insn ref手册声称操作数大小可能会被66H或REX.W覆盖的说法相反:
操作数大小。当前代码段描述符中的D标志确定默认操作数大小;可能
被指令前缀(66H或REX.W)覆盖。
操作数大小(16、32或64位)决定堆栈指针的递减量(2、4)
或(8)
注意,这是记录32位和64位模式。32位推送当然在32位模式下可用。(wiki提供手册链接)
由于有许多结构大小不能用一条指令推送,因此不可能有任何语法根据结构大小选择字、dword或qword操作数大小。不过,如果您真的愿意,您可以自己使用宏来完成
push
ing大型结构不是正常的调用约定的工作方式,所以这是它没有语法糖分的另一个原因。通常,太大而无法放入寄存器的对象是通过引用传递的。较小的对象可以通过值传递。因此您不能仅仅参数化推送的操作数大小来生成灵活的代码;根据结构的大小,您需要使用宏发出不同的指令来传递值和传递引用
由于您的结构是64位的,因此您只能在64位模式下用一条指令推送整个结构:
push qword [vec1]
push qword [vec2]
(如果FASM使用MASM语法而不是NASM,则为qword ptr
。sizeof.VEC
是一个数值表达式。在FASM中,8[vec1]
是否表示[vec1+8]
?如果是这样的话,这就是你得到的(如果你在操作数大小由其他东西暗示的上下文中使用它,或者与qword
或qword ptr
一起使用它)。无论如何,这只是一个如何让你的汇编程序用正确的操作数大小编码push[mem]
。(16位和64位推送可在64位模式下编码,但不能在32位推送模式下编码。REX.W=0将某些故障推送为非法指令,这与英特尔insn ref手册声称操作数大小可被66H
或REX.W
覆盖的说法相反)一般来说,正如您所指出的,我的问题是如何让汇编器使用正确的操作数大小对push[mem]进行编码,这在x86中是响应还是非法?这很简单:如果您的结构是16或64b,它们是。否则不是!sizeof.VEC
是一个数字表达式。是8[vec1]在FASM中的意思是[vec1+8]
?如果是这样的话,那就是你得到的(如果你在操作数大小由其他东西暗示的上下文中使用它,或者使用qword
或qword ptr
。无论如何,这只是一个如何让你的汇编程序用正确的操作数大小编码push[mem]
)的问题。(16位和64位推送可在64位模式下编码,但不能在32位推送模式下编码。REX.W=0将某些故障推送为非法指令,这与Intel的insn ref手册声称操作数大小可以被66H
或REX.W
覆盖的说法相反),正如您所指出的