Ubuntu22.04下如何编译XED语法X86汇编指令为可执行文件
没有直接对标NASM、MASM的原生支持XED语法的独立汇编器,但针对你做随机指令生成的场景,有两个非常成熟的落地方案,都能直接处理你列出的示例指令:
方案1:直接调用XED库/工具编码,对接自定义可执行文件生成流程
Ubuntu 22.04官方源已经提供了编译好的XED运行库和命令行工具,直接安装即可:sudo apt install libxed-dev xedXED本身就是UOPS站点XML数据使用的指令编解码底层,和XML里的指令定义100%对齐,不会出现编码和文档不匹配的问题,非常适合随机指令生成场景。
你给出的指令里,绝大多数可以直接作为参数传给xed命令生成机器码,只有{load}这类XED专属的指令属性标记需要单独处理:这类标记是用来标注指令访存行为的,不影响指令的二进制编码,调用时要么把属性作为参数传给xed,要么在预处理时过滤即可。
以你给出的示例指令为例,直接执行以下命令就能把所有指令编码成连续的64位模式机器码,输出到raw_code.bin文件:# 初始化空的机器码文件 truncate -s 0 raw_code.bin # 编码普通无特殊属性的指令,指定加载基址为0x400000(常规ELF默认加载基址) xed -64 -asm -ir "DEC R8W" -p 0x400000 >> raw_code.bin xed -64 -asm -ir "LOCK ADC byte ptr [0xB8], 0x82" -p 0x400000 >> raw_code.bin xed -64 -asm -ir "IN AX, DX" -p 0x400000 >> raw_code.bin xed -64 -asm -ir "BTR qword ptr [RBX], 0xF7" -p 0x400000 >> raw_code.bin xed -64 -asm -ir "IN EAX, DX" -p 0x400000 >> raw_code.bin xed -64 -asm -ir "ADD RAX, 0x25C9FB2C" -p 0x400000 >> raw_code.bin xed -64 -asm -ir "LOCK BTC qword ptr [RBP], 0xA5" -p 0x400000 >> raw_code.bin xed -64 -asm -ir "CMOVBE ESI, R10D" -p 0x400000 >> raw_code.bin # 编码带{load}属性的MOV指令,传入对应属性参数即可 xed -64 -asm -ir "MOV CH, DL" -attribute MLOAD -p 0x400000 >> raw_code.bin拿到原始机器码后,如果只是做指令执行测试,可以直接把机器码映射到带可执行权限的内存页运行;如果需要生成标准ELF可执行文件,写一个极简的链接脚本、搭配几行启动和退出的桩代码,用ld链接即可,不需要复杂的工具链。
方案2:轻量语法转换后对接NASM汇编器
如果你更熟悉现有汇编器的工作流,XED语法和NASM语法的兼容性极高,你列出的示例里99%的内容不需要修改就能被NASM识别,只需要做两步预处理:- 过滤掉行首的
{load}这类XED专属属性标记,这类标记不影响二进制编码,删除后不改变指令语义 - 确认使用Ubuntu 22.04源里自带的NASM 2.15及以上版本,该版本原生支持
byte ptr/qword ptr这类XED风格的内存操作数大小声明,不需要替换成NASM原生的byte/qword关键字
预处理完成后的指令可以直接写入NASM汇编文件,按常规流程汇编、链接生成可执行文件。
- 过滤掉行首的
注意:如果你的随机指令生成需要严格和UOPS提供的指令编码、时序数据对齐,优先选择方案1。NASM对部分多编码指令的编码选择可能和XED不一致,会导致生成的机器码和XML标注的指令行为、性能数据存在偏差,额外增加校验成本。
内容的提问来源于stack exchange,提问作者user10732596

