在x86-64程序集中打印一个数字

时间:2022-03-16 05:34:18

Okay, all I am trying to do is print a number (up to 18446744073709551616) in x86-64 assembly for Linux. Can anyone please tell me why this program will not work? All that happens is that it runs and exits. Thank you for all the help you can give!

好的,我想要做的就是在Linux的x86-64程序集中打印一个数字(最多18446744073709551616)。谁能告诉我为什么这个程序不起作用?所有这一切都是它运行和退出。感谢您提供的所有帮助!

GLOBAL _start
SECTION .text

;PRINTCHAR
; MOV [LETTER],RAX
; 
; MOV RAX,1
; MOV RDI,1
; MOV RSI,LETTER
; MOV RDX,1
; SYSCALL
; RET

PRINTDEC:
 MOV R9,18          ;SO IT CAN POINT TO THE END OF THE BUFFER
 MOV R10,0
 START:
 MOV R8,NUMBER
 MOV RDX,0          ;CLEAR OUT RDX TO AVOID ERRORS
 MOV RBX,10         ;WHAT TO DIVIDE BY

 DIV RBX            ;DIVIDE OUR NUMBER BY TEN

 CMP RAX,0          ;IF OUR QUOTENT IS ZERO THEN WE ARE DONE, PRINT THE BUFFER
 JE END
 JMP ADDBUF

 ADDBUF:
  ADD R8,R9         ;MOV TO THE CURRENT LOCATION IN OUR BUFFER
  ADD RDX,0x30
;  ADD R8,R10
  MOV [R8],RDX      ;MOV THE LAST NUMBER IN OUR BUFFER TO RDX
  DEC R9
  INC R10
  JMP START

 END:

 ADD R8,R9          ;add the very last digit
 MOV [R8],RDX
 INC R10

 MOV RAX,1
 MOV RDI,1
 MOV RSI,R8
 MOV RDX,R10
 SYSCALL

 RET

_start:
 MOV RAX,55
 CALL PRINTDEC

 MOV RAX,60
 MOV RDI,0
 SYSCALL

SECTION .bss
 LETTER: RESB 1
 NUMBER: RESB 19

1 个解决方案

#1


1  

PRINTDEC:
 LEA R9, [NUMBER + 18] ; last character of buffer
 MOV R10, R9         ; copy the last character address
 MOV RBX, 10         ; base10 divisor

 DIV_BY_10:

 XOR RDX, RDX          ; zero rdx for div
 DIV RBX            ; rax:rdx = rax / rbx
 ADD RDX, 0x30      ; convert binary digit to ascii
 TEST RAX,RAX          ; if rax == 0 exit DIV_BY_10
 JZ LAST_REMAINDER
 MOV byte [R9], DL       ; save remainder
 SUB R9, 1               ; decrement the buffer address
 JMP DIV_BY_10

 LAST_REMAINDER:

 TEST DL, DL       ; if DL (last remainder) != 0 add it to the buffer
 JZ CHECK_BUFFER
 MOV byte [R9], DL       ; save remainder
 SUB R9, 1               ; decrement the buffer address

 CHECK_BUFFER:

 CMP R9, R10       ; if the buffer has data print it
 JNE PRINT_BUFFER 
 MOV byte [R9], '0' ; place the default zero into the empty buffer
 SUB R9, 1

 PRINT_BUFFER:

 ADD R9, 1          ; address of last digit saved to buffer
 SUB R10, R9        ; end address minus start address
 ADD R10, 1         ; R10 = length of number
 MOV RAX, 1         ; NR_write
 MOV RDI, 1         ;     stdout
 MOV RSI, R9        ;     number buffer address
 MOV RDX, R10       ;     string length
 SYSCALL

 RET

#1


1  

PRINTDEC:
 LEA R9, [NUMBER + 18] ; last character of buffer
 MOV R10, R9         ; copy the last character address
 MOV RBX, 10         ; base10 divisor

 DIV_BY_10:

 XOR RDX, RDX          ; zero rdx for div
 DIV RBX            ; rax:rdx = rax / rbx
 ADD RDX, 0x30      ; convert binary digit to ascii
 TEST RAX,RAX          ; if rax == 0 exit DIV_BY_10
 JZ LAST_REMAINDER
 MOV byte [R9], DL       ; save remainder
 SUB R9, 1               ; decrement the buffer address
 JMP DIV_BY_10

 LAST_REMAINDER:

 TEST DL, DL       ; if DL (last remainder) != 0 add it to the buffer
 JZ CHECK_BUFFER
 MOV byte [R9], DL       ; save remainder
 SUB R9, 1               ; decrement the buffer address

 CHECK_BUFFER:

 CMP R9, R10       ; if the buffer has data print it
 JNE PRINT_BUFFER 
 MOV byte [R9], '0' ; place the default zero into the empty buffer
 SUB R9, 1

 PRINT_BUFFER:

 ADD R9, 1          ; address of last digit saved to buffer
 SUB R10, R9        ; end address minus start address
 ADD R10, 1         ; R10 = length of number
 MOV RAX, 1         ; NR_write
 MOV RDI, 1         ;     stdout
 MOV RSI, R9        ;     number buffer address
 MOV RDX, R10       ;     string length
 SYSCALL

 RET