title: How to print signed integer in x86 assembly (NASM) on Mac
body: <p>I found an <a href="https://codereview.stackexchange.com/questions/142842/integer-to-ascii-algorithm-x86-assembly">implementation</a> of unsigned integer conversion in x86 assembly, and I tried plugging it in but being new to assembly and not having a debugging env there yet, it's difficult to understand why it's not working. I would also like it to work with signed integers so it can capture error messages from syscalls.</p>
  
  <p>Wondering if one could show how to fix this code to get the signed integer to print, without using printf but using <code>strprn</code> provided by <a href="https://stackoverflow.com/questions/27594297/how-to-print-a-string-to-the-terminal-in-x86-64-assembly-nasm-without-syscall">this</a> answer.</p>
  
  <pre><code>%define a rdi
  %define b rsi
  %define c rdx
  %define d r10
  %define e r8
  %define f r9
  %define i rax
  
  %define EXIT 0x2000001
  %define EXIT_STATUS 0
  
  %define READ 0x2000003 ; read
  %define WRITE 0x2000004 ; write
  %define OPEN 0x2000005 ; open(path, oflag)
  %define CLOSE 0x2000006 ; CLOSE
  %define MMAP 0x2000197 ; mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset)
  
  ; szstr computes the lenght of a string.
  ; rdi - string address
  ; rdx - contains string length (returned)
  strsz:
    xor     rcx, rcx                ; zero rcx
    not     rcx                     ; set rcx = -1 (uses bitwise id: ~x = -x-1)
    xor     al,al                   ; zero the al register (initialize to NUL)
    cld                             ; clear the direction flag
    repnz scasb                     ; get the string length (dec rcx through NUL)
    not     rcx                     ; rev all bits of negative -&gt; absolute value
    dec     rcx                     ; -1 to skip the null-term, rcx contains length
    mov     rdx, rcx                ; size returned in rdx, ready to call write
    ret
  
  ; strprn writes a string to the file descriptor.
  ; rdi - string address
  ; rdx - contains string length
  strprn:
    push    rdi                     ; push string address onto stack
    call    strsz                   ; call strsz to get length
    pop     rsi                     ; pop string to rsi (source index)
    mov     rax, WRITE              ; put write/stdout number in rax (both 1)
    mov     rdi, 1        ; set destination index to rax (stdout)
    syscall                         ; call kernel
    ret
  
  ; mov ebx, 0xCCCCCCCD
  itoa:
    xor rdi, rdi
    call itoal
    ret
  
  ; itoa loop
  itoal:
    mov ecx, eax                    ; save original number
  
    mul ebx                         ; divide by 10 using agner fog's 'magic number'
    shr edx, 3                      ;
  
    mov eax, edx                    ; store quotient for next loop
  
    lea edx, [edx*4 + edx]          ; multiply by 10
    shl rdi, 8                      ; make room for byte
    lea edx, [edx*2 - '0']          ; finish *10 and convert to ascii
    sub ecx, edx                    ; subtract from original number to get remainder
  
    lea rdi, [rdi + rcx]            ; store next byte
  
    test eax, eax
    jnz itoal
  
  exit:
    mov a, EXIT_STATUS ; exit status
    mov i, EXIT ; exit
    syscall
  
  _main:
    mov rdi, msg
    call strprn
    mov ebx, -0xCCCCCCCD
    call itoa
    call strprn
    jmp exit
  
  section .text
  msg: db  0xa, "  Hello StackOverflow!!!", 0xa, 0xa, 0
  </code></pre>
  
  <p>With this working it will be possible to properly print signed integers to STDOUT, so you can log the registers values.</p>
  
  <ul>
  <li><a href="https://codereview.stackexchange.com/questions/142842/integer-to-ascii-algorithm-x86-assembly">https://codereview.stackexchange.com/questions/142842/integer-to-ascii-algorithm-x86-assembly</a></li>
  <li><a href="https://stackoverflow.com/questions/27594297/how-to-print-a-string-to-the-terminal-in-x86-64-assembly-nasm-without-syscall">How to print a string to the terminal in x86-64 assembly (NASM) without syscall?</a></li>
  <li><a href="https://stackoverflow.com/questions/13166064/how-do-i-print-an-integer-in-assembly-level-programming-without-printf-from-the/46301894">How do I print an integer in Assembly Level Programming without printf from the c library?</a></li>
  <li><a href="https://baptiste-wicht.com/posts/2011/11/print-strings-integers-intel-assembly.html" rel="nofollow noreferrer">https://baptiste-wicht.com/posts/2011/11/print-strings-integers-intel-assembly.html</a></li>
  <li><a href="https://stackoverflow.com/questions/55292583/how-to-get-length-of-long-strings-in-x86-assembly-to-print-on-assertion/55293496#55293496">How to get length of long strings in x86 assembly to print on assertion</a></li>
  </ul>