Unix 在NASM中打印负数

Unix 在NASM中打印负数,unix,assembly,nasm,x86-64,negative-number,Unix,Assembly,Nasm,X86 64,Negative Number,我在汇编语言(NASM)中的函数有问题。 我想知道为什么当我输入一个负数时,我的函数会输出一个无符号整数 我目前正在mac OSX上工作 我想知道是否有人能向我解释这个错误 我的原型: ;void ft_putnbr(int n); 当我在函数中输入负值时: -1我的功能打印4294954951 section .text global _ft_putnbr _ft_putnbr : push rbp mov

我在汇编语言(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                                 

int
是32位,但您使用64位算术。一个简单但难看的修复方法是将其扩展到64位,这样就不必更改代码的其余部分:而不是
mov-rbx,rdi
do
movsx-rbx,edi
。或者,将函数原型更改为使用64位类型,可能是
long

还要注意的是,在没有初始化的情况下使用
rsi
,这是非常糟糕的


PS:学习使用调试器。

int
是32位,但您使用64位算术。一个简单但难看的修复方法是将其扩展到64位,这样就不必更改代码的其余部分:而不是
mov-rbx,rdi
do
movsx-rbx,edi
。或者,将函数原型更改为使用64位类型,可能是
long

还要注意的是,在没有初始化的情况下使用
rsi
,这是非常糟糕的


PS:学习使用调试器。

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