x86汇编实现字符串字符遍历及ASCII值打印方法问询
解决x86汇编打印字符ASCII值的问题
要实现遍历字符串并打印每个字符的ASCII值,你需要解决两个核心问题:将8位无符号数转换为可打印的十进制字符串,以及修正现有代码中的错误逻辑。以下是完整的修改方案:
现有代码的问题点
- 输入读取错误:
read系统调用中ebx=2指向标准错误(stderr),应改为0(标准输入stdin)才能正确读取用户输入。 - 循环终止条件错误:用户输入的字符串不会自动以
0结尾,而是以换行符(0x0A)结束,用read返回的字节数控制循环更可靠。 - 缺少数字转字符串逻辑:Linux系统调用只能打印字符串,无法直接输出数字,必须先将ASCII值转换为十进制字符串。
修改后的完整代码
section .data prompt db "Enter your message: " prompt_len equ $-prompt newline db 10, 0 ascii_buf db '000', 10 ; 存储3位十进制ASCII值+换行,总长度4 ascii_buf_len equ $-ascii_buf section .bss buffer resb 255 section .text _start: ; 打印提示信息 mov eax, 4 mov ebx, 1 mov ecx, prompt mov edx, prompt_len int 0x80 ; 读取用户输入到buffer,修正文件描述符为0(stdin) mov eax, 3 mov ebx, 0 mov ecx, buffer mov edx, 255 int 0x80 mov ecx, eax ; 保存读取的字节数,用于控制循环 mov esi, buffer mov edi, ecx ; 循环计数器:剩余未处理的字符数 loop_start: cmp edi, 0 je done ; 所有字符处理完毕,退出循环 mov al, byte [esi] ; 读取当前字符到al call convert_to_decimal ; 将al中的ASCII值转为十进制字符串 ; 打印转换后的ASCII值 mov eax, 4 mov ebx, 1 mov ecx, ascii_buf mov edx, ascii_buf_len int 0x80 inc esi ; 指针移到下一个字符 dec edi ; 剩余字符数减1 jmp loop_start ; 子过程:将al中的8位无符号数(0-255)转为十进制字符串,存入ascii_buf convert_to_decimal: ; 计算百位 mov bl, 100 div bl ; al = 百位数字,ah = 余数 add al, '0' ; 转成ASCII字符 mov [ascii_buf], al ; 计算十位 mov al, ah ; 余数存入al mov bl, 10 div bl ; al = 十位数字,ah = 个位数字 add al, '0' mov [ascii_buf+1], al ; 计算个位 add ah, '0' mov [ascii_buf+2], ah ret done: ; 退出程序 mov eax, 1 mov ebx, 0 int 0x80
关键修改说明
- 输入读取修正:将
ebx设为0,确保从标准输入读取用户输入。 - 循环控制优化:用
read返回的字节数作为循环计数器,准确处理所有输入字符,包括换行符(其ASCII值为10)。 - 数字转字符串实现:通过除法分解百位、十位、个位,将每个数字转为ASCII字符存入缓冲区,再调用
write系统调用打印。 - 移除冗余逻辑:删掉了原代码中无意义的
cmp esi, buffer判断,每个字符都需要处理。
内容的提问来源于stack exchange,提问作者c0ncatenate
相关产品推荐
相关产品推荐

