You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在汇编中从ASCII表获取字符编码?需编写NASM程序实现显示功能

嘿,这两个问题我来帮你搞定!先从ASCII编码的推导说起,再给你写一个能用NASM编译的完整程序~

从ASCII表推导字符对应的编码

其实ASCII表的核心就是字符与十进制/十六进制数值的一一映射,推导起来很简单,记住几个关键基准点就能举一反三:

  • 数字字符:'0'对应的十进制ASCII编码是48,所以'1'就是48+1=49,以此类推,'9'就是48+9=57(也就是你示例里的数值)。
  • 大写字母:'A'的十进制编码是65,'B'就是66,直到'Z'是65+25=90。
  • 小写字母:'a'的十进制编码是97,和对应的大写字母差32(比如'a' = 'A' +32),所以'z'就是97+25=122。
  • 特殊字符:比如空格是32,换行是10,回车是13,这些特殊值大多需要直接记,但如果是相邻的同类特殊字符,也能顺推(不过这类情况不多)。

举个实际例子:想知道'X'的编码,先确认它是大写字母,'A'是65,'X'是第24个大写字母(A算第1个),所以65+23=88,没错,'X'的ASCII十进制就是88。

NASM汇编程序:输入字符并输出其ASCII编码

下面是一个基于Linux 32位系统的NASM汇编程序,能实现你要的功能:提示输入字符,然后输出该字符和对应的十进制ASCII编码,和你给的示例格式完全一致。

section .data
    ; 提示用户输入的文本
    prompt          db  'Enter a character: '
    prompt_len      equ $ - prompt
    ; 输出前缀文本
    output_prefix   db  'You entered '
    prefix_len      equ $ - output_prefix
    ; 分隔符
    separator       db  ' | '
    sep_len         equ $ - separator
    ; 换行符
    newline         db  0xA
    newline_len     equ $ - newline

section .bss
    input_char      resb 1   ; 存储用户输入的单个字符
    ascii_str_buf   resb 3   ; 存储ASCII值的十进制字符串(最多3位)

section .text
    global _start

_start:
    ; 1. 显示输入提示
    mov eax, 4          ; Linux系统调用号:sys_write
    mov ebx, 1          ; 文件描述符:stdout(标准输出)
    mov ecx, prompt
    mov edx, prompt_len
    int 0x80            ; 触发系统调用

    ; 2. 读取用户输入的一个字符
    mov eax, 3          ; Linux系统调用号:sys_read
    mov ebx, 0          ; 文件描述符:stdin(标准输入)
    mov ecx, input_char
    mov edx, 1          ; 读取1个字节
    int 0x80

    ; 3. 输出前缀文本
    mov eax, 4
    mov ebx, 1
    mov ecx, output_prefix
    mov edx, prefix_len
    int 0x80

    ; 4. 输出用户输入的字符
    mov eax, 4
    mov ebx, 1
    mov ecx, input_char
    mov edx, 1
    int 0x80

    ; 5. 输出分隔符
    mov eax, 4
    mov ebx, 1
    mov ecx, separator
    mov edx, sep_len
    int 0x80

    ; 6. 将ASCII值转换为十进制字符串
    movzx eax, byte [input_char]  ; 读取字符的ASCII值(无符号扩展到32位)
    call num_to_dec_str           ; 调用转换函数,结果存在ascii_str_buf

    ; 7. 转换后输出ASCII值
    mov eax, 4
    mov ebx, 1
    ; 转换函数已经把ecx设为字符串起始地址,edx设为字符串长度
    int 0x80

    ; 8. 输出换行
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, newline_len
    int 0x80

    ; 9. 退出程序
    mov eax, 1          ; Linux系统调用号:sys_exit
    mov ebx, 0          ; 退出码0(正常退出)
    int 0x80

; 函数:num_to_dec_str
; 输入:eax = 要转换的无符号整数(0-255,符合ASCII范围)
; 输出:ecx = 转换后的字符串起始地址,edx = 字符串长度
num_to_dec_str:
    mov ebx, ascii_str_buf + 2  ; 指向缓冲区最后一位(从后往前填)
    mov ecx, 10                 ; 除数:十进制的基数

convert_loop:
    xor edx, edx                ; 清空edx,因为div使用edx:eax作为被除数
    div ecx                     ; eax = eax / 10,edx = eax % 10(余数)
    add dl, '0'                 ; 把余数转换为ASCII字符
    mov [ebx], dl               ; 存入缓冲区
    dec ebx                     ; 指针左移一位
    test eax, eax               ; 判断被除数是否已经为0
    jnz convert_loop            ; 不为0继续循环

    ; 计算字符串起始地址和长度
    mov ecx, ebx + 1            ; 第一个有效数字的地址
    mov edx, ascii_str_buf + 3 - ecx  ; 字符串长度
    ret

编译和运行步骤:

  1. 把上面的代码保存为ascii_char.asm
  2. 用NASM编译成32位目标文件:
    nasm -f elf32 ascii_char.asm -o ascii_char.o
    
  3. 用ld链接成可执行文件:
    ld -m elf_i386 ascii_char.o -o ascii_char
    
  4. 运行程序:
    ./ascii_char
    
    输入一个字符(比如9),就会输出:You entered 9 | 57,和你要的示例完全一致!

内容的提问来源于stack exchange,提问作者Денис Лебедев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:02:34