x86-32 Intel汇编单字符无法打印问题排查求助
汇编单字节输出失败的问题分析与解决
核心问题
你的代码存在两个关键错误:
write系统调用参数类型错误:Linux 32位的write系统调用(eax=4)要求ecx传入的是要输出数据的内存地址,而非直接的字节数值。你把字节值(比如0x32)直接赋值给ecx,write会尝试从地址0x32处读取数据——这个低地址属于无效内存区域,读不到有效内容,自然没有输出。- 输出长度设置错误:你把
edx设为15,这会让write尝试读取15个字节,但你只需要输出单个字节,这个值应该改成1。
另外还有一个规范问题:原代码里的section .start是错误的,正确的代码段应该是section .text,部分汇编器可能兼容错误写法,但不符合标准规范。
修正方案(两种可选)
方案1:新增字节变量存储输出内容
global _start section .data buffer: times 100 db 0 output_byte: db 0 ; 专门用来存放要输出的单个字节 section .text _start: ; 读取输入到缓冲区 mov eax, 3 mov ebx, 0 mov ecx, buffer mov edx, 10 int 80h ; 提取缓冲区第2个字节(index=1)并存入变量 movzx esi, byte [buffer+1] mov [output_byte], esi print: ; 调用write输出单个字节 mov eax, 4 mov ebx, 1 mov ecx, output_byte ; 传入变量的内存地址 mov edx, 1 ; 输出长度设为1 int 80h exit: mov eax, 1 mov ebx, 0 int 80h
方案2:利用栈临时存储字节(无需新增变量)
如果不想额外定义变量,可以把字节压入栈,直接取栈顶的内存地址传给ecx:
global _start section .data buffer: times 100 db 0 section .text _start: mov eax, 3 mov ebx, 0 mov ecx, buffer mov edx, 10 int 80h ; 提取字节并压栈 movzx esi, byte [buffer+1] push esi print: mov eax, 4 mov ebx, 1 lea ecx, [esp] ; 取栈顶的内存地址,而非弹出字节值 mov edx, 1 int 80h pop esi ; 清理栈,避免栈不平衡 exit: mov eax, 1 mov ebx, 0 int 80h
额外说明
movzx的使用是正确的,它把单个字节零扩展到32位寄存器,避免了符号扩展带来的问题。- 你用
gdb看到字节存入ecx是对的,但ecx里的是数值而非地址,这是关键误解点。
内容的提问来源于stack exchange,提问作者Aleph_0
相关产品推荐
相关产品推荐

