【问题标题】:print a negative number in NASM在 NASM 中打印一个负数
【发布时间】:2016-01-07 12:21:30
【问题描述】:

我的汇编语言 (NASM) 函数有问题。 我想知道为什么当我输入一个负数时,我的函数会打印一个无符号整数。

我目前正在使用 mac OSX。

我想知道是否有人可以向我解释这个错误。

我的原型:

;void    ft_putnbr(int n);

当我在函数中输入负值时:

-1 我的函数打印 4294954951。

section .text

global  _ft_putnbr

_ft_putnbr  :
    push    rbp                         
    mov     rbp, rsp                    
    xor     rbx, rbx                    
    mov     rbx, rdi                    
    cmp     rbx, 0x0                    
    jge     _printnb                    
    neg     rbx                         
    mov     rax, SYS_WRITE               
    mov     rdi, 1                      
    mov     [rsi], byte 45              
    mov     rdx, 1                      
    syscall                             

_printnb        :
    cmp     rbx, 0x9                    
    jg      _recursion                  
    mov     [rsi], byte 48              
    add     [rsi], rbx                   
    mov     rdi, 1                      
    mov     rax, SYS_WRITE              
    mov     rdx, 1                       
    syscall                             
    jmp     _return                     

_recursion  :
    xor     rdx, rdx                    
    xor     rax, rax                    
    mov     rcx, 10                     
    mov     rax, rbx                    
    div     rcx                          
    push    rdx                         
    mov     rdi, rax                    
    call    _ft_putnbr                     
    pop     rdi                         
    call    _ft_putnbr                     
    jmp     _return                     

_return     :
    leave                               
    ret                                 

【问题讨论】:

  • 你应该打印到堆栈上的一个小缓冲区,然后write(2),而不是每个字符进行一次系统调用。此外,在用其他内容覆盖之前,您不需要将寄存器归零。 mov rbx, rdi 不依赖于 rbx 的旧内容。我还打破了在那里产生旧值的依赖链,就像 xor same,same 一样(这是 xor 的特例,但不是 mov,因为 mov 从不依赖旧值)。

标签: unix assembly nasm x86-64 negative-number


【解决方案1】:

int 是 32 位,但您使用的是 64 位算术。一个简单但丑陋的解决方法是将其符号扩展为 64 位,这样您就不必更改其余代码:而不是 mov rbx, rdimovsx rbx, edi。或者,将函数原型更改为使用 64 位类型,可能是 long

还要注意你使用rsi 没有初始化,这很糟糕。

PS:学习使用调试器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-17
    • 2013-10-12
    • 2015-08-26
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多