GAS与NASM的RIP相对寻址差异:全局变量加载代码转换
在NASM中实现RIP相对寻址访问stdin/stdout的正确方式
GAS与NASM的RIP相对寻址语法存在差异,你遇到的symbol 'rip' not defined报错,是因为NASM不支持GAS那种symbol[rip]的写法。要实现和原GAS代码完全一致的功能,需要改用NASM的RIP相对寻址语法:
正确语法
将原来的两行代码替换为:
mov rdx, qword [rel stdin] mov rdx, qword [rel stdout]
[rel symbol]是NASM中64位模式下RIP相对寻址的标准写法,它会让汇编器生成基于当前指令指针(RIP)偏移的地址引用,和GAS的symbol[rip]语义完全匹配,同时符合PIC(位置无关代码)的要求——这也是GCC默认生成RIP相对寻址代码的原因。
完整示例代码
对应的C++原函数
#include <cstdio> void echo_input() { char buf[1024]; fgets(buf, sizeof(buf), stdin); fputs(buf, stdout); }
修正后的NASM实现
extern fgets extern fputs extern stdin extern stdout section .text global echo_input echo_input: push rbp mov rbp, rsp sub rsp, 1024 ; 为buf分配栈空间 ; 调用fgets: char* fgets(char* s, int size, FILE* stream) mov rdi, rsp mov esi, 1024 mov rdx, qword [rel stdin] ; RIP相对寻址加载stdin地址 call fgets ; 调用fputs: int fputs(const char* s, FILE* stream) mov rdi, rsp mov rdx, qword [rel stdout] ; RIP相对寻址加载stdout地址 call fputs leave ret
补充说明
如果编译静态链接程序(非PIC模式),NASM默认可能使用绝对寻址,但加上rel前缀依然可以强制生成RIP相对寻址代码,保证和原GAS代码的行为完全一致。
内容的提问来源于stack exchange,提问作者digito_evo
相关产品推荐
相关产品推荐

