Assembly 将数字转换为四进制/ASCII

Assembly 将数字转换为四进制/ASCII,assembly,x86-64,Assembly,X86 64,[汇编x86-64] 具体来说,我试图将137799转换为四进制,然后转换为ASCII值,该值应为“3830B”,但我得到的是“3830;”,因此我的最后一个数字出于某种原因是错误的。这是我的密码: ; Part 1 - Successive division mov eax, dword [iNum1] ; get the integer 137,799 mov rcx, 0 ; digitCount = 0 mov ebp, 14 ; set for dividing by 14 div

[汇编x86-64]

具体来说,我试图将137799转换为四进制,然后转换为ASCII值,该值应为“3830B”,但我得到的是“3830;”,因此我的最后一个数字出于某种原因是错误的。这是我的密码:

; Part 1 - Successive division

mov eax, dword [iNum1] ; get the integer 137,799
mov rcx, 0 ; digitCount = 0
mov ebp, 14 ; set for dividing by 14

divideLoop:
            mov edx, 0
            div ebp ; divide by 14

            push rdx ; push remainder
            inc rcx

            cmp eax, 0 
            jne divideLoop
; -----
; Part 2 - Convert remainders and store

mov rbx, num1String ; get addr of string
mov rsi, 0 ; index = 0 

popLoop:
        pop r8
        add r8b, "0" ; converting to ASCII

        mov byte [rbx+rsi], r8b
        inc rsi
        loop popLoop    

mov byte [rbx+rsi], NULL

我看不出我做错了什么。任何帮助都将不胜感激。

您的错误是将您得到的号码添加到字母“0”中:

    add r8b, "0" ; converting to ASCII
这适用于数字,因为
0
9
在ASCII中是连续的,但在数字之后,在字母表开始之前有一些符号。看看这张表:

最简单的方法是在程序中添加一个查找表(“0123456789AB”),然后使用得到的数字为正确的字符编制索引

table: .string "0123456789AB"
// ...
mov r8b, [table+r8b]

您的错误是将您得到的号码添加到字母“0”中:

    add r8b, "0" ; converting to ASCII
这适用于数字,因为
0
9
在ASCII中是连续的,但在数字之后,在字母表开始之前有一些符号。看看这张表:

最简单的方法是在程序中添加一个查找表(“0123456789AB”),然后使用得到的数字为正确的字符编制索引

table: .string "0123456789AB"
// ...
mov r8b, [table+r8b]

看看ASCII表。字母A,B,C。。。不要直接跟随9。请注意,
循环
效率低下(但可能不会比
div
慢),并且不需要按下/弹出。从缓冲区的末尾开始。有关简单的base-10函数的信息,请参阅(您可以在其中插入表格查找,而不是
添加edx,'0'
)。请查看ASCII表格。字母A,B,C。。。不要直接跟随9。请注意,
循环
效率低下(但可能不会比
div
慢),并且不需要按下/弹出。从缓冲区的末尾开始。有关简单的base-10函数的信息,请参阅(您可以在其中插入表格查找,而不是
add edx,'0'
)。请注意
symbol+register
仅适用于符号位于低32位地址空间(例如Linux,而不是OS X)的系统上的位置相关代码。但是,是的,数字表查找是一种将基数转换为大于10的好方法。在PIE/PIC代码中,您可能希望表基址位于RIP相对LEA的寄存器中,但在寻址模式下使用表基址在可用时是很好的。请注意,
symbol+register
仅适用于符号位于低32位地址空间(例如Linux而非OS X)的系统上的位置相关代码。但是,是的,数字表查找是一种将基数转换为大于10的好方法。在PIE/PIC代码中,您可能需要RIP相对LEA的寄存器中的表基址,但在寻址模式中正确使用表基址是很好的。