在 x86 中将结构类型的内容推入堆栈
Pushing contents of struct type onto the stack in x86
假设我已经声明了一个这样的结构:
struct VEC
x dd ?
y dd ?
ends
然后我将一些数据声明为结构:
section '.data' data readable writeable
vec1 VEC 5,4
vec2 VEC 3,2
现在,我想将内存位置vec1 和vec2 的内容压入堆栈。我这样做:
push sizeof.VEC [vec1]
push sizeof.VEC [vec2]
这无法编译。返回的错误是:
error: operand size not specified.
我想知道有没有办法把这个struct类型的内容放到栈上。或者这首先在 x86 中是非法的?
我正在 Windows 10 上使用平面汇编程序版本 1.71.49
进行编译
一般来说,我的问题是关于如何让汇编程序使用正确的操作数大小对推送 [mem] 进行编码
这只是一个关于如何让您的汇编程序使用正确的操作数大小对 push [mem]
进行编码的问题。 16 位和 64 位 push
es 可以在 64 位模式下编码,但 32 位 push
es 不能。 REX.W=0 push something
作为非法指令出错,这与 Intel 的 insn ref 手册声称操作数大小可能被 66H 或 REX.W:
覆盖相反
Operand size. The D flag in the current code-segment descriptor determines the default operand size; it may
be overridden by instruction prefixes (66H or REX.W).
The operand size (16, 32, or 64 bits) determines the amount by which the stack pointer is decremented (2, 4
or 8).
请注意,这是记录 32 位和 64 位模式。 32 位推送当然可以在 32 位模式下使用。 (x86 手册链接的 wiki)
由于有很多结构大小无法通过一条指令推送,因此不太可能有任何语法可以根据结构大小选择字、双字或四字操作数大小。不过,如果您确实需要,您可以自己使用宏来完成。
push
大型结构不是正常调用约定的工作方式,因此这是没有语法糖的另一个原因。通常太大而无法放入寄存器的对象通过引用传递。较小的对象可以按值传递。所以你不能只参数化push
的操作数大小来制作灵活的代码;您需要使用宏来发出不同的指令以按值传递与按引用传递,具体取决于结构的大小。
由于您的结构是 64 位的,您只能在 64 位模式下使用一条指令推送整个结构:
push qword [vec1]
push qword [vec2]
(或 qword ptr
,如果 FASM 使用 MASM 语法而不是 NASM)。
假设我已经声明了一个这样的结构:
struct VEC
x dd ?
y dd ?
ends
然后我将一些数据声明为结构:
section '.data' data readable writeable
vec1 VEC 5,4
vec2 VEC 3,2
现在,我想将内存位置vec1 和vec2 的内容压入堆栈。我这样做:
push sizeof.VEC [vec1]
push sizeof.VEC [vec2]
这无法编译。返回的错误是:
error: operand size not specified.
我想知道有没有办法把这个struct类型的内容放到栈上。或者这首先在 x86 中是非法的?
我正在 Windows 10 上使用平面汇编程序版本 1.71.49
进行编译一般来说,我的问题是关于如何让汇编程序使用正确的操作数大小对推送 [mem] 进行编码
这只是一个关于如何让您的汇编程序使用正确的操作数大小对 push [mem]
进行编码的问题。 16 位和 64 位 push
es 可以在 64 位模式下编码,但 32 位 push
es 不能。 REX.W=0 push something
作为非法指令出错,这与 Intel 的 insn ref 手册声称操作数大小可能被 66H 或 REX.W:
Operand size. The D flag in the current code-segment descriptor determines the default operand size; it may be overridden by instruction prefixes (66H or REX.W). The operand size (16, 32, or 64 bits) determines the amount by which the stack pointer is decremented (2, 4 or 8).
请注意,这是记录 32 位和 64 位模式。 32 位推送当然可以在 32 位模式下使用。 (x86 手册链接的 wiki)
由于有很多结构大小无法通过一条指令推送,因此不太可能有任何语法可以根据结构大小选择字、双字或四字操作数大小。不过,如果您确实需要,您可以自己使用宏来完成。
push
大型结构不是正常调用约定的工作方式,因此这是没有语法糖的另一个原因。通常太大而无法放入寄存器的对象通过引用传递。较小的对象可以按值传递。所以你不能只参数化push
的操作数大小来制作灵活的代码;您需要使用宏来发出不同的指令以按值传递与按引用传递,具体取决于结构的大小。
由于您的结构是 64 位的,您只能在 64 位模式下使用一条指令推送整个结构:
push qword [vec1]
push qword [vec2]
(或 qword ptr
,如果 FASM 使用 MASM 语法而不是 NASM)。