将数字转换为可打印格式时,通常最容易从最后一位开始。
考虑将 123 转换为“123”,我们如何获得最后一位?这是除以 10(底数)时的余数。所以 123 % 10 给了我们 3 并且 123 / 10 = 12 方便地给了我们在下一次迭代中使用的正确数字。在 x86 上,“DIV”指令足以为我们提供商和余数(分别为 inax
和dx
)。剩下的就是在字符串中存储可打印的字符。
将所有这些放在一起,您最终会得到以下内容(使用 nasm 语法):
; ConvertNumber
; Input:
; ax = Number to be converted
; bx = Base
;
; Output:
; si = Start of NUL-terminated buffer
; containing the converted number
; in ASCII represention.
ConvertNumber:
push ax ; Save modified registers
push bx
push dx
mov si, bufferend ; Start at the end
.convert:
xor dx, dx ; Clear dx for division
div bx ; Divide by base
add dl, '0' ; Convert to printable char
cmp dl, '9' ; Hex digit?
jbe .store ; No. Store it
add dl, 'A'-'0'-10 ; Adjust hex digit
.store:
dec si ; Move back one position
mov [si], dl ; Store converted digit
and ax, ax ; Division result 0?
jnz .convert ; No. Still digits to convert
pop dx ; Restore modified registers
pop bx
pop ax
ret
这需要一个工作缓冲区(在 base = 2 的情况下需要 16 个,并且 NUL 终止符需要一个额外的字节):
buffer: times 16 db 0
bufferend:
db 0
添加对签名数字的支持留给读者作为练习。这是适用于 64 位汇编的大致相同的例程。