汇编:如何将数据转换为Ascii

时间:2016-01-10 07:53:27

标签: assembly nasm

我已经制作了一个程序来在x64汇编语言(nasm)中添加数组的元素。但是当我显示总和时,它显示了一些其他不可读的结果。所以我询问了它,我发现我需要将总和转换为ASCII格式然后显示它。但我无法弄清楚这部分代码的作用。我已将该部分代码嵌入到我的程序中,现在它工作正常,但我无法理解这段代码实际上做了什么。这是我的计划:

global _start

section .data
arr1 dq 0000000000000001h,0000000000000002h,0000000000000003h,0000000000000004h,0000000000000005h
carry db 00

msg1 db 'Addition Is:',10
len1 equ $-msg1
msg2 db  " "
len2 equ $-msg1

section .bss
addition resb 16

section .text
_start: 
mov cl,4
mov rsi,arr1
mov rax,[rsi]
up: add rsi,8
add rax,[rsi]
jnc a1
inc byte[carry]

a1:   dec cl
jnz up

call display            ;ASCII conversion procedure display called

mov rax,1
mov rdi,1
mov rsi,msg1
mov rdx,len1
syscall


add byte[carry],30h
mov rax,1
mov rdi,1
mov rsi,carry
mov rdx,1
syscall




mov rax,1
mov rdi,1
mov rsi,addition
mov rdx,16
syscall

mov rax,60
mov rdi,0
syscall

display:mov rdi,addition        ;How this procedure converts the addition into ASCII
    mov cl,16
up1:    rol rax,4
    mov rbx,rax
    and rax,0Fh
    cmp rax,09h
    ja dn1
    add rax,30h
    jmp dn
dn1:    add rax,37h
dn: mov [rdi],rax
    mov rax,rbx
    inc rdi
    dec cl
    jnz up1
    ret

1 个答案:

答案 0 :(得分:1)

我已经用注释解释了代码的相关部分,这些注释解释了正在发生的事情。我将假设你知道base16算术和按位逻辑是如何工作的。如果没有,您将不得不在维基百科或其他地方查看。

    mov cl,16      ; The loop counter (there are 16 digits)
up1:    rol rax,4  ; Rotate the contents of rax 4 bits to the left. What were
                   ; previously the 4 most significant bits will now be in
                   ; the 4 least significant bits of rax. This is done because
                   ; we want to print the most significant digit first. 
    mov rbx,rax    ; Make a copy of the rotated version of rax.
    and rax,0Fh    ; Keep the 4 least significant bits of rax and set all other
                   ; bits of rax to 0.
    cmp rax,09h    ; rax will now be in the range 0..15. Is it greater than 9?
    ja dn1         ; ..if so, jump to dn1.
    add rax,30h    ; rax was in the range 0..9. The characters '0'..'9' are encoded as
                   ; 30h..39h in ASCII, so add 30h to convert into a character.
    jmp dn         ; We're done with this case.
dn1:    add rax,37h ; rax is in the range 10..15. The characters 'A'..'F' are encoded as
                    ; 41h..46h in ASCII, so add 37h to convert into a character.
dn: mov [rdi],rax  ; Store the character in the buffer pointed to by rdi.
    mov rax,rbx    ; Restore rax to the value it had right after the rol. So on the
                   ; next iteration we'll be processing what were originally the
                   ; second most significant 4 bits, and so on.
    inc rdi        ; Increment the buffer pointer.
    dec cl         ; Decrement the loop counter.
    jnz up1        ; Repeat for all 16 digits.