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
覆盖的说法相反),正如您所指出的