x86汇编开发base64编码器时如何修改bss段equ定义的常量值
问题根源
你用equ定义的OutputBufLen是汇编期常量,汇编阶段就会被直接替换成立即数4,不属于内存中可修改的变量,所以你尝试写内存的mov [OutputBufLen], 3、dec等操作完全不会生效,因为本质是在对立即数地址做非法操作。同时你原来的打印逻辑汇编后会直接变成mov rdx, 4,永远固定输出4字节。
解决方法
有两种常用实现方案,按需选择即可:
方案1:新增可修改的长度变量
第一步,修改段定义,把固定常量替换为可读写的长度变量,同时补充你遗漏的输出缓冲区定义:
SECTION .bss OutputBuf resb 4 ; 4字节输出缓冲区,原逻辑不变 OutputBufLen resb 1 ; 1字节变量,存储实际需要输出的长度,可动态修改
第二步,在处理输入的逻辑中,根据实际读入的输入长度,动态给变量赋值:
; 示例逻辑:假设实际输入的字节数存在al寄存器中 cmp al, 1 je .len_2 cmp al, 2 je .len_3 ; 默认输入3字节,输出4字节 mov byte [OutputBufLen], 4 jmp .print .len_2: mov byte [OutputBufLen], 2 jmp .print .len_3: mov byte [OutputBufLen], 3 .print:
第三步,修改打印逻辑,读取内存中的长度值到rdx寄存器,注意要用movzx做零扩展,避免读到高位垃圾数据:
printOutputBuf: mov rax, 1 mov rdi, 1 mov rsi, OutputBuf movzx rdx, byte [OutputBufLen] ; 读动态长度到rdx syscall ret
方案2:直接动态给rdx赋值(更高效)
如果不需要长期存储长度值,可以在调用打印前直接把计算好的输出长度放到rdx寄存器,不需要额外开变量:
; 处理输入后直接给rdx赋值 ; 输入1字节时执行:mov rdx, 2 ; 输入2字节时执行:mov rdx, 3 ; 输入3字节时执行:mov rdx, 4 printOutputBuf: mov rax, 1 mov rdi, 1 mov rsi, OutputBuf ; rdx已经提前存好要输出的长度,直接调用syscall即可 syscall ret
内容的提问来源于stack exchange,提问作者WasteD
相关产品推荐
相关产品推荐

