使用NASM预处理器计算校验和
在NASM生成的原始二进制末尾追加校验和字节
方法一:汇编阶段直接计算并追加(纯NASM实现)
如果你的代码和数据可以通过宏逐个定义,可在预处理阶段累计校验和,最后直接输出校验字节:
; 定义宏:添加字节同时累计校验和 %macro add_byte 1 db %1 %assign checksum (checksum + %1) & 0xFF ; 用&0xFF取低8位,可按需调整校验规则 %endmacro ; 初始化校验和为0 %assign checksum 0 ; 替换成你的实际代码/数据 add_byte 0x11 add_byte 0x22 add_byte 0x33 add_byte 0xB8 ; mov eax, 0 的机器码 add_byte 0x00 add_byte 0x00 add_byte 0x00 add_byte 0x00 ; 最后追加校验和字节 db checksum
核心是通过宏把字节定义与校验和计算绑定,让NASM在预处理阶段完成校验和累加,直接输出结果。
方法二:分两步处理(汇编后用外部工具追加)
若代码结构复杂,不方便用宏逐个定义字节,可先汇编出原始二进制,再用脚本或命令行工具计算并追加校验和:
- 先汇编生成二进制文件:
nasm -f bin your_program.asm -o your_program.bin
- 用Python脚本计算并追加(灵活易读):
with open('your_program.bin', 'rb+') as f: content = f.read() # 以所有字节的和取低8位作为校验和,可按需修改规则 checksum = sum(content) & 0xFF f.write(bytes([checksum]))
或用bash命令行工具(无需Python):
# 计算所有字节的和并取模256 checksum=$(xxd -p your_program.bin | tr -d '\n' | fold -w2 | awk '{s += strtonum("0x"$1)} END {print s % 256}') # 将校验和转为十六进制字节追加到文件 printf "\\x$(printf %02x $checksum)" >> your_program.bin
为什么直接用%rep遍历原始字节不可行?
NASM的%rep是预处理阶段指令,执行时机早于汇编阶段。而原始二进制的字节是汇编后的产物,预处理阶段无法访问这些字节的实际值,因此没法直接用%rep遍历计算。
内容的提问来源于stack exchange,提问作者user10328353
相关产品推荐
相关产品推荐

