如何进一步缩短Linux平台AArch64汇编版Hello World的机器码?
优化AArch64 "Hello World" 汇编代码的建议
首先,你已经做了非常出色的精简工作,从504字节压缩到124字节,尤其是用跳转复用mov x0,0来节省指令的思路,简直是个小妙招!针对你的现有代码,这里有几个可以进一步精简的方向:
1. 移除标签,用PC相对偏移减少符号表开销
你的代码里用了j:标签和b j跳转,逻辑没问题,但标签会在ELF文件的符号表中占用额外条目。可以把b j替换成PC相对的直接偏移跳转,这样能删掉符号表中的j条目,缩小文件整体大小:
mov x8, 64 // __NR_write adr x1, hello // 字符串地址 mov x2, 10 // 字符串长度 mov x0, 0 // 移除j:标签 svc 0 mov x8, 93 // __NR_exit b .-16 // 跳回上面的mov x0,0(偏移根据实际指令长度计算,此处为16字节) hello: .ascii "HelloWorld"
2. 将字符串嵌入代码段,减少段表开销
默认情况下,字符串可能会被放在单独的数据段,这会增加ELF的段表、节表等元数据的大小。把字符串直接放在代码末尾(紧跟跳转指令之后),让它属于代码段,这样可以减少一个数据段的元数据,进一步压缩文件体积——上面的示例已经这么做了。
3. 用movz替代mov加载立即数(规范优化,不减少长度但更灵活)
AArch64中,mov x8, #64和movz x8, #0x40的指令长度都是4字节,但movz是加载立即数的标准指令,如果你后续需要扩展立即数(比如用movk拼接更高位)会更灵活,代码也更符合AArch64的编码规范:
movz x8, #0x40 // __NR_write(64的十六进制是0x40) adr x1, hello movz x2, #10 movz x0, #0 svc 0 movz x8, #0x5D // __NR_exit(93的十六进制是0x5D) b .-16 hello: .ascii "HelloWorld"
4. 链接阶段的进阶优化(进一步压缩文件)
如果你的目标是最小化可执行文件大小,还可以在链接时加上这些选项:
--strip-all:移除所有符号表和调试信息--nmagic:取消节的对齐要求,减少空字节填充--no-dynamic-linker:因为这是静态无依赖的程序,不需要动态链接器
比如用ld链接时:
ld -o hello hello.o --strip-all --nmagic --no-dynamic-linker
这能进一步压缩ELF的元数据大小。
需要说明的是,你当前用b j复用mov x0,0的思路已经是指令层面非常高效的做法了——exit系统调用必须设置x0=0,跳转复用这条指令比额外写一条mov x0,0节省了4字节,这个优化已经做得非常到位啦!
内容的提问来源于stack exchange,提问作者gXLg
相关产品推荐
相关产品推荐

