Tuesday, November 16, 2021

[SOLVED] print a negative number in NASM

Issue

I have a problem with my function in assembly language (NASM). I want to know why, when I enter a negative number, my function prints an unsigned int.

I'm currently working on mac OSX.

I wonder if someone could explain the error to me.

My prototype :

;void    ft_putnbr(int n);

When I enter a negative value in my function :

-1 my function print 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                                 

Solution

int is 32 bits, but you use 64 bit arithmetic. A simple but ugly fix is to sign extend it to 64 bits so you don't have to change the rest of the code: instead of mov rbx, rdi do movsx rbx, edi. Alternatively, change the function prototype to use a 64 bit type, probably long.

Also note that you use rsi without initialization, and that's very bad.

PS: learn to use a debugger.



Answered By - Jester