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

如何在GCC汇编中使用call getchar@PLT逐个读取字符串字符并验证输入

问题需求

需要将以下C代码转换为x86汇编,要求使用getchar@PLT逐个读取输入字符,完成循环输入与验证逻辑:

puts("Enter a string of 0s and 1s: ");
while ( ((input = getchar()) != '\n') ) {
    if ( (input != '0') && (input != '1') ) { // invalid input
        puts("ERROR: invalid input");
        return 1;
    }
}

用户已完成部分汇编代码(仅实现提示打印与简单读取),现需补充循环逻辑、getchar@PLT调用及输入验证功能:

.section .data
input_prompt:
.asciz "Enter a string of 0s and 1s: "
invalid_message:
.asciz "Invalid input: program terminating\n"
newline:
.byte 10
state:
.int 0  # initial state (EE)

.section .bss
input:
.byte 0

.section .text
globl main

main:
# Print the input prompt
movl $4, %eax        # syscall: write
movl $1, %ebx        # file descriptor: stdout
lea input_prompt, %ecx  # pointer to the message
movl $29, %edx       # message length
int $0x80            # invoke syscall

# Read user input
movl $3, %eax        # syscall: read
movl $0, %ebx        # file descriptor: stdin
lea input, %ecx      # buffer to store input
movl $4, %edx        # buffer size
int $0x80            # invoke syscall

实现方法

1. 替换系统调用为getchar@PLT调用

getchar()从标准输入读取单个字符,32位x86调用约定下返回值存在%eax寄存器(字符内容在低8位%al中),直接调用即可逐个获取输入,无需保留原read系统调用。

2. 实现循环逻辑

循环核心流程:调用getchar → 判断是否为换行符 → 是则退出循环,否则验证字符有效性:

  • 用jmp直接进入循环入口;
  • 调用getchar@PLT后,将%al与换行符(0xA)比较,通过je(相等则跳转)指令退出循环。

3. 输入验证逻辑

获取字符后,依次判断是否为'0'(ASCII码0x30)或'1'(ASCII码0x31):

  • 匹配'0'或'1'则回到循环开头,继续读取下一个字符;
  • 若都不匹配,打印错误信息并返回1终止程序。

4. 完整汇编代码

.section .data
input_prompt:
.asciz "Enter a string of 0s and 1s: "
invalid_message:
.asciz "ERROR: invalid input\n"

.section .text
globl main

main:
    # 打印输入提示
    movl $4, %eax
    movl $1, %ebx
    lea input_prompt, %ecx
    movl $29, %edx
    int $0x80

loop_start:
    # 调用getchar读取单个字符,返回值存在%eax(低8位%al为字符)
    call getchar@PLT

    # 判断是否为换行符,是则退出循环
    cmpb $0xA, %al
    je loop_exit

    # 验证是否为'0',是则继续循环
    cmpb $0x30, %al
    je loop_start

    # 验证是否为'1',是则继续循环
    cmpb $0x31, %al
    je loop_start

    # 输入无效:打印错误信息
    movl $4, %eax
    movl $1, %ebx
    lea invalid_message, %ecx
    movl $20, %edx       # 错误信息长度
    int $0x80

    # 返回1表示程序异常终止
    movl $1, %eax
    movl $1, %ebx
    int $0x80

loop_exit:
    # 正常退出程序,返回0
    movl $1, %eax
    movl $0, %ebx
    int $0x80

关键细节说明

  • getchar@PLT是动态链接libc的过程链接表条目,无需手动处理函数地址;
  • 字符比较用cmpb(字节比较),因为单个字符占1字节;
  • 原代码中未用到的.bss段、state、newline变量可直接移除,简化代码结构;
  • 退出程序使用exit系统调用(%eax=1),返回值通过%ebx传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 18:53:10