AT&T 32位汇编中call指令后定义的字符串为何能传递到ebx寄存器?
代码逻辑解答
这是32位Linux汇编中非常典型的位置无关字符串传递技巧,常见于Shellcode编写场景,核心逻辑如下:
- 首先明确汇编伪指令
.string的作用:它不会在运行时执行,只是在汇编编译阶段,直接把字符串的二进制字节插入到指令流的当前位置,也就是call A指令的后面,不存在「call执行后才定义字符串」的情况。 - 程序执行顺序:
- 入口
_start首先执行jmp B跳转到标签B - 执行
call A指令时,x86 32位架构的call指令会自动完成两个操作:- 将
call指令的下一条内存地址(也就是后面字符串的首地址)压入栈顶 - 跳转到标签A执行后续代码
- 将
- 进入标签A后执行
popl %ebx,会把栈顶存放的、刚才call压入的字符串首地址直接弹出到ebx寄存器,刚好符合32位Linuxint 0x80系统调用的约定:open的系统调用号为5(存放在al),第一个参数文件路径指针存放在ebx,第二个参数打开模式存放在ecx(这里xorl %ecx, %ecx就是设置为O_RDONLY)。
- 入口
内容的提问来源于stack exchange,提问作者sharlit mals
相关产品推荐
相关产品推荐

