数値を印刷可能な形式に変換する場合、多くの場合、最後の桁から始めるのが最も簡単です。
123 を "123" に変換することを考えてみましょう。最後の桁はどのように取得しますか? 10で割った余り(底)です。したがって、123 % 10 から 3 が得られ、123 / 10 = 12 から次の反復で使用する正しい数値が得られます。ax
x86 では、「DIV」命令は、商と剰余の両方を (それぞれとで) 与えるのに十分便利です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 ビット アセンブリに適合したほぼ同じルーチンです。