tal*_*alz 0 x86 assembly att addressing-mode
鉴于数据:
.section data
data_set:
.long 2,5,33,54,2,76,4,37,43,223,98,70,255
Run Code Online (Sandbox Code Playgroud)
如何将数据的起始地址(而不是该地址中的值)推送到堆栈?
我试过这个:
pushl data_set
Run Code Online (Sandbox Code Playgroud)
最终(在尝试访问此地址中的数据之后)导致了段错误。
在 AT&T 语法中,要将地址用作指令的立即操作数,请使用$label.
你想要pushl $data_set的push imm32指令。,就像你一样push $123。
pushl data_set将推送从地址加载的双字数据data_set,即
push m32。
从概念上讲,AT&T 语法将所有内容都视为潜在地址。所以label是一个地址,所以是0x123。因此,add 0x123, %eax从地址的负载0x123,并add label, %eax从该地址的负载label。当您想要一个数字作为直接操作数时,您可以使用add $0x123, %eax. 使用符号地址作为立即操作数的工作原理相同。
无论哪种方式,地址都被编码到指令中,这只是在寻址模式下它是立即数还是位移的问题。这就是为什么您使用
add $(foo - bar), %eax添加两个符号之间的距离,而不是
add $foo-$bar, %eax(这将查找名为 的符号$bar,即$符号名称的一部分)。将$适用于整个操作数,而不是符号/标签名称。相关:更多关于 GAS 中的组装时间数学
在其他上下文中,例如作为.longor的操作数.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);
}
Run Code Online (Sandbox Code Playgroud)
让 C 编译器发出将符号地址传递给函数的代码。我把它放在Godbolt 编译器资源管理器上,它确实使用了pushl $data.
| 归档时间: |
|
| 查看次数: |
1862 次 |
| 最近记录: |