Printing an integer with x86 32-bit Linux sys_write (NASM)

后端 未结 1 1444
不思量自难忘°
不思量自难忘° 2020-12-20 09:54

I\'m new to this forum. I have a little experience with high-level languages (really little). Nearly one month ago I thought it would be a good idea to see how assembly work

相关标签:
1条回答
  • 2020-12-20 10:14

    Your numbers will quickly grow larger than just a single digit. What you ought to be doing is have an integer in num rather than a character, and then convert that integer into a string that you can print with sys_write.

    Here's one way of doing the conversion: repeated division by 10, getting the lowest digit first as the remainder:

    ; Input:
    ; eax = integer value to convert
    ; esi = pointer to buffer to store the string in (must have room for at least 10 bytes)
    ; Output:
    ; eax = pointer to the first character of the generated string
    ; ecx = length of the generated string
    int_to_string:
      add esi,9
      mov byte [esi],0    ; String terminator
    
      mov ebx,10
    .next_digit:
      xor edx,edx         ; Clear edx prior to dividing edx:eax by ebx
      div ebx             ; eax /= 10
      add dl,'0'          ; Convert the remainder to ASCII 
      dec esi             ; store characters in reverse order
      mov [esi],dl
      test eax,eax            
      jnz .next_digit     ; Repeat until eax==0
    
      ; return a pointer to the first digit (not necessarily the start of the provided buffer)
      mov eax,esi
      ret
    

    Which you can use like this:

        mov    dword [num],1
        ...
        mov    eax,[num]       ; function args using our own private calling convention
        mov    esi,buffer
        call   int_to_string
    ; eax now holds the address that you pass to sys_write
        ...
    
    section .bss
        num    resd 1
        buffer resb 10
    

    Your number-doubling can be simplified to shl dword [num],1. Or better, double it at some point while it's still in a register with add eax,eax.

    0 讨论(0)
提交回复
热议问题