not_here_to_play
not_here_to_play

Reputation: 158

printing integer backwards in assembly for macos x86_64

I am trying to print an integer in assembly x86_64 on macOS. I already know there are roughly 3/4 answers but I could not solve my problem.

For now, I would be satisfied to print it backwards. So, this is the code:

section .bss                                                            
  3 number_back                 resb                3                       
  4 number_right                resb                3                       
  5                                                                         
  6 section .text                                                           
  7     global _main                                                        
  8 _main:                                                                  
  9     mov rax, 123                                                        
 10     call _get_backwards                                                 
 11                                                                         
 12     mov rax, 0x2000004                                                  
 13     mov rdi, 1                                                          
 14     mov rsi, number_back                                                
 15     mov rdx, 3                                                          
 16     syscall                                                             
 17                                                                         
 18     mov rax, 0x2000001                                                  
 19     xor rdi, rdi                                                        
 20     syscall                                                             
 21                                                                         
 22 _get_backwards:                                                         
 23     xor rdx, rdx                                                        
 24     mov rcx, 10                                                         
 25     div rcx                                                             
 26     add rdx, 48                                                         
 27     mov [rel number_back], rdx                                          
 28                                                                         
 29 loop:                                                                   
 30     inc number_back                                                     
 31     cmp rax, 0                                                          
 32     jne _get_backwards                                                  
 33     ret                     

Explanation

  1. mov rax, 123 ; move number into rax register
  2. call get_backwards procedure
  3. division and mult require 2 registers, one for the quotient one for the remainder.Xor the remainder so I get rid of all the garbage
  4. mov into rcx, 10 so that I can get the remainder which corresponds to the last digit of the number, 3 in this case
  5. divide rax by rcx
  6. get the ascii code of the int
  7. move the content of the rdx register into the memory address held by the pointer number_back
  8. here is the part that causes problems. I’d like to do somthing like number_back[0] = 3, number_back[1] = 2 ... . I thought that increasing the pointer by one would make trick, but I am not correct. I am getting this error
error: invalid combination of opcode and operands
  1. If rax is 0 exit otherwise loop

Thank you in advance.

Upvotes: 1

Views: 134

Answers (1)

laenNoCode
laenNoCode

Reputation: 254

you can't increment a label as it is not stored anywhere in memory, just a named alias that will be replaced by the address to the memory you allocated. The way to do it would be to have an extra register (RBX is free right now) to store the offset you need to add to your address. An other problem with your code is that you will store a (ten) base representation of your value as word in you backward number, which will exceed your capacity. I guess that you are trying to print your number in the "normal" left to right way. What you should do is to reserve some more space if you want to do it this way (3bytes => 8 characters).

section .bss                                                            
 number_back                 resb                8; 8 characters                       
 number_right                resb                3   
section .text
    global _main
    _main:
     mov rax, 123 
     mov rbx, 0                                                       
     call _get_backwards                                                 
                                                                         
     mov rax, 0x2000004                                                  
     mov rdi, 1                                                          
     mov rsi, number_back                                                
     mov rdx, 3                                                          
     syscall                                                             
                                                                         
     mov rax, 0x2000001                                                  
     xor rdi, rdi                                                        
     syscall                                                             
                                                                         
 _get_backwards:                                                         
     xor rdx, rdx                                                        
     mov rcx, 10                                                         
     div rcx                                                             
     add rdx, 48                                                         
     mov [rel number_back + rbx], rdx                                          
                                                                         
 loop:                                                                   
     inc rbx                                                    
     cmp rax, 0                                                          
     jne _get_backwards                                                  
     ret     

should work (I don't have a nasm compiler on this computer sorry).

Upvotes: 0

Related Questions