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

64位NASM汇编程序栈中字符无法输出问题求助

64位NASM汇编程序无输出问题修复

我是Nick,一名学生,作业要求用64位NASM汇编编写程序:将数字629拆分为6、2、9并依次入栈,出栈后转为字符串逐个打印。代码可正常编译,但始终无输出,困扰两天,求验证修复。(代码中novi_red=换行,stampaj=打印,petlja=循环)

原代码

section .data
    novi_red db ' ', 10    
    number dd 629
section .text
    global _start
    stampaj:
        push rax
        push rbx
        mov eax, 4         
        mov ebx, 1         
        int 0x80           
        pop rbx
        pop rax
        ret
_start:
    mov eax, [number]
    mov ecx, 3  
petlja:
    mov ebx, 10  
    xor edx, edx  
    div ebx  
    add dl, '0'  
    push rdx  
    dec ecx  
    cmp ecx, 0  
    jne petlja  
    pop rax
    mov ebx, 1
    mov rcx, rax
    mov edx, 1
    call stampaj
    mov edx, 2
    mov ecx, novi_red
    call stampaj
    pop rax
    mov rcx, rax
    call stampaj
    mov edx, 2
    mov ecx, novi_red
    call stampaj
    pop rax
    mov rcx, rax
    call stampaj   
    mov eax, 1
    xor ebx, ebx
    int 0x80

问题点

  1. 系统调用参数错误:
    • 32位int 0x80的write调用(eax=4)要求参数为:ebx=文件描述符,ecx=缓冲区地址,edx=长度。但原代码调用stampaj前,把字符值存在rcx,stampaj未做处理就传递错误地址给ecx,导致无输出。
    • 64位环境混用32位系统调用时,错误使用rcx寄存器(32位调用需用ecx而非rcx)。
  2. 字符传递方式错误:
    • 直接将字符值存入rcx作为缓冲区地址,属于非法内存访问,系统不会输出任何内容。

修复代码

section .data
    novi_red db 10        ; 简化为纯换行符
    number dd 629
    temp_char db 0        ; 临时存储单个打印字符
section .text
    global _start

    ; 打印单个字符:al = 要打印的ASCII字符
    stampaj_char:
        push rbx
        push rcx
        push rdx
        mov [temp_char], al  ; 将字符写入临时内存缓冲区
        mov eax, 4           ; 32位write系统调用号
        mov ebx, 1           ; stdout文件描述符
        mov ecx, temp_char   ; 缓冲区地址
        mov edx, 1           ; 打印长度1
        int 0x80
        pop rdx
        pop rcx
        pop rbx
        ret

    ; 打印换行
    stampaj_novi_red:
        push rax
        mov al, [novi_red]
        call stampaj_char
        pop rax
        ret

_start:
    mov eax, [number]
    mov ecx, 3  
petlja:
    mov ebx, 10  
    xor edx, edx  
    div ebx  
    add dl, '0'  
    push rdx  
    dec ecx  
    cmp ecx, 0  
    jne petlja  

    ; 出栈打印6
    pop rax
    mov al, al  ; 取rax低8位(原dl中的字符)
    call stampaj_char
    call stampaj_novi_red

    ; 出栈打印2
    pop rax
    mov al, al
    call stampaj_char
    call stampaj_novi_red

    ; 出栈打印9
    pop rax
    mov al, al
    call stampaj_char
    call stampaj_novi_red

    ; 退出程序
    mov eax, 1
    xor ebx, ebx
    int 0x80

修复说明

  1. 新增临时缓冲区:用temp_char存储要打印的字符,满足write系统调用对内存地址的要求。
  2. 修正打印函数:stampaj_char负责将字符写入缓冲区并执行系统调用,参数传递完全符合int 0x80的规则。
  3. 简化换行逻辑:单独封装stampaj_novi_red函数,避免重复代码。
  4. 修正字符提取:出栈后取rax的低8位al作为打印字符,确保传递正确的ASCII值。

编译运行指令:

nasm -f elf64 yourfile.asm -o yourfile.o
ld yourfile.o -o yourfile
./yourfile

运行后会依次输出6、2、9,每个字符占一行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 01:56:10