【问题标题】:Printing a number in x86-64 assembly在 x86-64 程序集中打印一个数字
【发布时间】:2013-07-25 15:40:50
【问题描述】:

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

【问题讨论】:

    标签: linux assembly 64-bit x86-64


    【解决方案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
    

    【讨论】:

    • No.... 我正在尝试在 RAX 中打印号码,该号码是在 _start 中调用 PRINTDEC 之前定义的。
    • @KyleMartin - 你说得对,我已经为你重写并评论了 PRINTDEC 方法。
    • 老兄!谢谢!这是对我所能做的巨大改进......但是,您的代码仍然没有打印出第一个数字.. 我要看看它,看看我能做什么,但我认为我应该让你知道。谢谢!
    • 好的,我修好了。只需在 PRINT_BUFFER 后添加这两行: 1:MOV byte [R9],DL 2: SUB R9,1
    • @KyleMartin - 好了,我在 RAX 为零后添加了一个检查 DL 中的最终余数。对不起,我一直在浏览器中写答案,显然我脑子里的编译器没有它应该的那么好。
    猜你喜欢
    • 1970-01-01
    • 2012-03-11
    • 1970-01-01
    • 2014-08-07
    • 2011-05-13
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    相关资源
    最近更新 更多