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

如何在amd64 GAS汇编中读取键盘输入字符并显示到屏幕

amd64平台GAS汇编实现键盘输入读取与屏幕显示

先解决你卡壳的ioctl cmd参数问题:amd64 Linux下和termios相关的常用ioctl命令值可以直接使用,不需要依赖头文件定义:

  • TCGETS:值为0x5401,传入指向termios结构体的缓冲区指针,内核会把当前终端的配置写入该缓冲区
  • TCSETS:值为0x5402,传入修改后的termios结构体指针,内核会立刻更新终端配置
  • 终端默认开启规范输入模式(canonical mode):输入内容会存在行缓冲区里,只有按下回车后程序才能通过read读到内容,同时默认开启输入回显,你敲的字符会自动显示在屏幕上。你给出的预期运行效果用默认模式就能实现,不需要修改终端配置。

最简可运行实现(匹配预期效果)

直接调用Linux原生read/write系统调用即可,不需要操作ioctl,完整代码如下:

.section .data
prompt:     .ascii "please input some character: "
prompt_len  = . - prompt
buf:        .space 128  # 预留128字节存储输入内容

.section .text
.global _start
_start:
    # 打印输入提示
    movq    $1, %rax        # sys_write系统调用号
    movq    $1, %rdi        # 参数1:文件描述符stdout=1
    movq    $prompt, %rsi   # 参数2:提示字符串首地址
    movq    $prompt_len, %rdx # 参数3:字符串长度
    syscall

    # 读取键盘输入
    movq    $0, %rax        # sys_read系统调用号
    movq    $0, %rdi        # 参数1:文件描述符stdin=0
    movq    $buf, %rsi      # 参数2:缓冲区首地址
    movq    $128, %rdx      # 参数3:最大读取长度
    syscall
    # read执行完成后,rax存储实际读到的字节数(包含末尾输入的回车符)

    # 将读到的内容输出到屏幕
    movq    %rax, %rdx      # 写入长度取read返回的实际读取长度
    movq    $1, %rax
    movq    $1, %rdi
    movq    $buf, %rsi
    syscall

    # 退出程序
    movq    $60, %rax       # sys_exit系统调用号
    movq    $0, %rdi        # 退出码0
    syscall

编译运行命令:

as -o program.o program.s
ld -o program program.o
chmod +x program
./program

运行后会直接匹配你给出的效果:打印提示字符串,输入内容按回车后,程序会原样输出你输入的内容。

扩展:逐字符即时读取实现

如果需要实现敲键即读、不需要按回车的效果,才需要用ioctl修改termios配置,核心是关闭c_lflag字段里的ICANON(规范模式)和ECHO(自动回显)位。amd64平台下termios结构体关键偏移:

  • c_lflag字段偏移12字节,占4字节
  • c_cc配置数组中,VMIN(最小读取字符数)偏移17字节,VTIME(读取超时)偏移16字节
    核心配置代码片段:
# 预留36字节空间存储termios结构,仅修改需要的配置位即可
termios_buf: .space 36

# 读取终端原有配置
movq    $16, %rax       # sys_ioctl系统调用号
movq    $0, %rdi        # stdin文件描述符
movq    $0x5401, %rsi   # TCGETS命令
movq    $termios_buf, %rdx
syscall

# 修改配置:关闭ICANON(值0x2)、ECHO(值0x8)位
andb    $0xF5, termios_buf+12  # c_lflag偏移12字节,清对应标志位
movb    $0, termios_buf+16     # VTIME设为0,不设读取超时
movb    $1, termios_buf+17     # VMIN设为1,读到1个字符就返回

# 写回修改后的配置
movq    $16, %rax
movq    $0, %rdi
movq    $0x5402, %rsi   # TCSETS命令
movq    $termios_buf, %rdx
syscall

# 后续read调用会逐字符返回,不需要等回车,且输入不会自动回显,需自行调用write输出读到的字符

注意如果修改了终端配置,程序退出前需要把原有配置恢复,否则终端会出现输入不显示、换行异常的问题。


内容的提问来源于stack exchange,提问作者OnlyWick

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:12:19