x86汇编两次输出字符串至控制台异常问题排查
x86汇编多字符串输出乱码问题解决
问题场景
作为x86汇编新手,编写控制台输出程序时,单个字符串输出正常,但添加第二个字符串后出现乱码。
单字符串正常代码:
section .data str: db "0000", 0xA len: db 5 global _start section .text _start: ; system call to print the string mov eax, 4 ; "write" system call mov ebx, 1 ; Indicates to write to standard out mov ecx, str ; The string mov edx, [len] ; The length of the string int 0x80 ; exit the program mov eax, 1 mov ebx, 0 int 0x80
添加第二个字符串后的出错代码:
section .data str: db "0000", 0xA len: db 5 otherStr: db "1111", 0xA otherLen: db 5 global _start section .text _start: ; system call to print the string mov eax, 4 ; "write" system call mov ebx, 1 ; Indicates to write to standard out mov ecx, str ; The string mov edx, [len] ; The length of the string int 0x80 ; system call to print the string mov eax, 4 ; "write" system call mov ebx, 1 ; Indicates to write to standard out mov ecx, otherStr ; The string mov edx, [otherLen] ; The length of the string int 0x80 ; exit the program mov eax, 1 mov ebx, 0 int 0x80
错误输出:
0000 1111 (# / 6 sha.asmstrlenotherStrotherLen__bss_start_edata_end.symtab.strtab.shstrtab.text.dat:! ;!'1111
预期输出:
0000 1111
使用环境:Fedora Linux,NASM汇编器,编译链接命令:
nasm -f elf32 example.asm -o ex1.o ld -m elf_i386 ex1.o -o ex1
错误原因
32位Linux的write系统调用(eax=4)要求edx参数传递32位(双字)长度值,但你用db定义了长度变量(仅占1字节)。当执行mov edx, [len]时,32位寄存器edx会从内存中读取连续4个字节——除了len本身的1字节,剩下3字节会读取到后面的otherStr、otherLen等数据,导致实际传递给系统调用的长度远大于预期,从而输出了多余的内存内容,出现乱码。
第一个程序能正常运行是巧合:len后面没有其他数据,读取的多余3字节可能是零值,刚好长度参数正确,所以输出正常。
修复方法
有两种可行的修复方式:
方式1:用双字定义长度变量
把db改成dd(定义32位双字),确保每个长度变量占4字节,mov edx, [len]会正确读取完整的32位长度值:
section .data str: db "0000", 0xA len: dd 5 ; 用dd定义双字长度 otherStr: db "1111", 0xA otherLen: dd 5 ; 用dd定义双字长度 global _start section .text _start: ; 输出第一个字符串 mov eax, 4 mov ebx, 1 mov ecx, str mov edx, [len] int 0x80 ; 输出第二个字符串 mov eax, 4 mov ebx, 1 mov ecx, otherStr mov edx, [otherLen] int 0x80 ; 退出程序 mov eax, 1 mov ebx, 0 int 0x80
方式2:零扩展字节到32位寄存器
保持db定义长度,使用movzx指令将字节数据零扩展为32位,避免读取多余内存:
; 替换原有的 mov edx, [len] movzx edx, byte [len] ; 替换原有的 mov edx, [otherLen] movzx edx, byte [otherLen]
内容的提问来源于stack exchange,提问作者HexagonalSmile
相关产品推荐
相关产品推荐

