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

x86汇编中访问字符串字符及首字符打印失效问题求助

问题描述

从标准输入读取字符串后,输出该字符串并打印其首字符。编写的x86汇编代码能正常读取和输出字符串,但打印首字符的部分完全无效。编译命令为:gcc -m32 filename.S -o filename -no-pie

汇编代码如下:

.data
mesaj: .space 11                   # the string to be read
formatScanf: .asciz "%s"
formatPrintf: .asciz "%s"
endl: .asciz "\n"

.text

.global main
main:

push $mesaj
push $formatScanf
call scanf
pop %ebx
pop %ebx

push $mesaj
push $formatPrintf
call printf
pop %ebx
pop %ebx

pushl $0
call fflush
popl %ebx

push $endl
push $formatPrintf
call printf
pop %ebx
pop %ebx

pushl $0
call fflush
popl %ebx

# Print the first letter of the string
movl $0, %edx
mov $mesaj, %edi
mov $4, %eax  # System call number for write
mov $1, %ebx  # File descriptor: 1 for standard output
mov $1, %ecx  # Number of bytes to print
movb (%edi), %dl  # Load the first byte (character) of the string into DL register

int $0x80      # Call the kernel to write the character

pushl $0
call fflush
popl %ebx

movl $1, %eax
movl $0, %ebx
int $0x80
问题排查与修正

问题出在write系统调用的参数传递错误:

  • Linux 32位系统调用write的参数约定是:
    • %eax:系统调用号(4对应write)
    • %ebx:文件描述符(1是标准输出)
    • %ecx:指向要写入数据的内存地址
    • %edx:要写入的字节数

你的代码里错误地把%ecx设为1(字节数),把首字符放到%dl(%edx的低8位),这不符合系统调用的参数要求。write会把%ecx的值当作内存地址去取数据,而地址1是无效的,所以没有输出。

修正后的首字符打印代码如下:

# Print the first letter of the string
mov $4, %eax  # System call number for write
mov $1, %ebx  # File descriptor: 1 for standard output
mov $mesaj, %ecx  # 指向要输出的首字符的地址
mov $1, %edx  # 要输出的字节数(1个字符)
int $0x80      # Call the kernel to write the character

解释:

  • 直接把mesaj的地址传给%ecx,因为mesaj就是字符串首字符的内存位置
  • 把要输出的字节数1放到%edx
  • 不需要用到%edi寄存器,直接用%ecx传递地址即可

这样修改后,write系统调用就能正确读取mesaj地址处的1个字节并输出到标准输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:18:15