Ubuntu下NASM+LD环境中global _start的位置与符号替换问题
关于NASM中global伪指令的两个问题解答
嘿,刚学汇编两天就抠这些细节,说明你很会思考嘛!针对你在Ubuntu上用NASM+ld遇到的两个问题,我给你一一捋清楚:
问题1:global _start能不能放在.text段外面?
完全可以!global是NASM的伪指令,核心作用是把指定符号导出给链接器(ld)识别,它的位置并不绑定任何代码段或数据段。不管你把它写在文件最开头、.data段定义之后,甚至所有段的前面,语法上都是合法的,链接器也能正常识别这个导出的入口符号。
举个实际可行的例子:
global _start ; 放在.text段定义之前,完全没问题 section .data msg db "Hello", 0xa section .text _start: mov eax, 1 mov edi, 1 mov rsi, msg mov edx, 6 syscall mov eax, 60 xor edi, edi syscall
编译链接后能正常运行,和把global _start放在.text段里的效果完全一致。
问题2:global后的_start能不能换成其他符号?
可以换,但要注意链接器的默认行为:
- NASM本身不会报错,因为
global只是负责导出符号,只要符号符合NASM的标识符规则(比如_asd、qwe都没问题),语法上完全合法。 - 但ld默认会找
_start作为程序的入口点,如果你换成了自定义符号却不额外指定,直接用ld test.o -o test链接的话,ld会报错找不到入口符号,或者给出警告后用默认地址作为入口,导致程序运行崩溃。
解决方法很简单:链接时用-e参数指定你的自定义入口符号,比如:
- 汇编代码:
global qwe ; 自定义入口符号 section .text qwe: ; 这里的符号要和global导出的完全一致 mov eax, 60 xor edi, edi syscall
- 编译链接命令:
nasm -f elf64 test.asm -o test.o ld -e qwe test.o -o test ; 用-e参数指定入口为qwe
这样程序就能正常以qwe作为入口点运行了。
内容的提问来源于stack exchange,提问作者Piamoon
相关产品推荐
相关产品推荐

