При преобразовании чисел в формат для печати часто проще всего начать с последней цифры.
Рассмотрите возможность преобразования 123 в "123", как бы мы получили последнюю цифру?Это осталось при делении на 10 (база).Таким образом, 123% 10 дает нам 3, а 123/10 = 12 удобно дает нам правильное число для работы в следующей итерации.На x86 инструкция «DIV» достаточно хороша, чтобы дать нам как частное, так и остаток (в ax
и 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
Для этого требуется рабочий буфер(16 для случая, когда base = 2 и дополнительный байт для терминатора NUL):
buffer: times 16 db 0
bufferend:
db 0
Добавление поддержки для чисел со знаком оставлено в качестве упражнения для читателя. Здесь - примерно та же самая процедура, адаптированная для 64-битной сборки.