程序集,x86:如何将标签推送到堆栈?
Assembly, x86: How to push a label to the stack?
给定数据:
.section data
data_set:
.long 2,5,33,54,2,76,4,37,43,223,98,70,255
如何将数据的起始地址(而不是该地址中的值)压入堆栈?
我试过这个:
pushl data_set
最终(在尝试访问该地址中的数据之后)导致了段错误。
在 AT&T 语法中,要将地址用作指令的直接操作数,请使用 $label
。
你想要 pushl $data_set
用于 push imm32
指令。,就像你 push 3
.
pushl data_set
将推送从地址 data_set
加载的双字数据,即
push m32
.
从概念上讲,AT&T 语法将所有内容都视为潜在地址。所以label
是地址,0x123
也是地址。因此 add 0x123, %eax
从地址 0x123
加载,而 add label, %eax
从地址 label
加载。当你想要一个数字作为立即操作数时,你可以使用 add [=24=]x123, %eax
。使用符号地址作为立即操作数的工作方式相同。
无论哪种方式,地址都编码到指令中,只是寻址方式中是立即数还是位移的问题。这就是你使用
的原因
add $(foo - bar), %eax
添加两个符号之间的距离,而不是
add $foo-$bar, %eax
(它会寻找一个名为 $bar
的符号,即 $
是符号名称的一部分)。 $
适用于整个操作数,不适用于符号/标签名称。相关:more about assemble-time math in GAS
在其他情况下,例如作为 .long
或 .quad
的操作数,不存在直接与内存操作数的问题,因此您只需编写 dataptr: .long data_set
即可发出 4 个字节的数据,其中包含 data_set
的地址,就像你从 C static int *dataptr = data_set;
得到的一样
您可以通过查看
的 C 编译器输出来检查语法
void ext(int*);
static int data[] = {1,2,3};
void foo() {
ext(data);
}
让 C 编译器生成将符号地址传递给函数的代码。我把它放在 the Godbolt compiler explorer 上,它确实使用了 pushl $data
.
给定数据:
.section data
data_set:
.long 2,5,33,54,2,76,4,37,43,223,98,70,255
如何将数据的起始地址(而不是该地址中的值)压入堆栈?
我试过这个:
pushl data_set
最终(在尝试访问该地址中的数据之后)导致了段错误。
在 AT&T 语法中,要将地址用作指令的直接操作数,请使用 $label
。
你想要 pushl $data_set
用于 push imm32
指令。,就像你 push 3
.
pushl data_set
将推送从地址 data_set
加载的双字数据,即
push m32
.
从概念上讲,AT&T 语法将所有内容都视为潜在地址。所以label
是地址,0x123
也是地址。因此 add 0x123, %eax
从地址 0x123
加载,而 add label, %eax
从地址 label
加载。当你想要一个数字作为立即操作数时,你可以使用 add [=24=]x123, %eax
。使用符号地址作为立即操作数的工作方式相同。
无论哪种方式,地址都编码到指令中,只是寻址方式中是立即数还是位移的问题。这就是你使用
的原因
add $(foo - bar), %eax
添加两个符号之间的距离,而不是
add $foo-$bar, %eax
(它会寻找一个名为 $bar
的符号,即 $
是符号名称的一部分)。 $
适用于整个操作数,不适用于符号/标签名称。相关:more about assemble-time math in GAS
在其他情况下,例如作为 .long
或 .quad
的操作数,不存在直接与内存操作数的问题,因此您只需编写 dataptr: .long data_set
即可发出 4 个字节的数据,其中包含 data_set
的地址,就像你从 C static int *dataptr = data_set;
您可以通过查看
的 C 编译器输出来检查语法void ext(int*);
static int data[] = {1,2,3};
void foo() {
ext(data);
}
让 C 编译器生成将符号地址传递给函数的代码。我把它放在 the Godbolt compiler explorer 上,它确实使用了 pushl $data
.