GCC编译16位汇编代码时标签地址被意外截断却无警告
GCC编译16位汇编代码时标签地址被意外截断却无警告
嘿,我最近在用GCC处理16位汇编代码时碰到了个挺坑的问题——标签地址明明超出了16位寄存器的范围,结果被直接截断成低16位,可GCC全程没给任何警告或错误提示,折腾好一会儿才搞清楚状况,来跟大家唠唠:
问题场景
我想把一个指定偏移位置的标签加载到16位寄存器%ax里,结果生成的二进制里地址直接被截断了,关键是编译器居然没报错,这完全不符合预期啊!
最小复现代码
先给大家看我的测试汇编文件test.S:
.text .global _start .code16 _start: movw $label, %ax .org 0x8000 label:
编译参数
我编译时指定了.text段的起始地址为0x8000,用的命令是:
gcc -Ttext=0x8000 -Werror -m16 -nostdlib -nostartfiles -no-pie -o test.out test.S
预期与实际结果
按道理算,label的实际地址应该是.text起始地址0x8000加上.org的偏移0x8000,也就是0x10000,这个值明显超过了16位寄存器能存储的最大值0xFFFF,我本来以为开启了-Werror会直接报错,结果GCC居然顺利编译通过了!
之后我用objdump反编译查看结果,发现0x10000被硬生生截断成了0x0:
objdump -S test.out > test.asm test.out: file format elf32-i386 Disassembly of section .text: 00008000 <_start>: 8000: b8 00 00 mov $0x0,%ax
有没有同行遇到过类似的问题?或者知道GCC为什么会允许这种地址溢出却不给出提示吗?
备注:内容来源于stack exchange,提问作者Thousand Pine
相关产品推荐
相关产品推荐

