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

时间:2013-07-25 15:40:51

标签: linux assembly 64-bit x86-64

好的,我要做的就是在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 个答案:

答案 0 :(得分: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