すでに Linux を使用している場合は、自分で変換する必要はありません。代わりに printf を使用してください:
;
; assemble and link with:
; nasm -f elf printf-test.asm && gcc -m32 -o printf-test printf-test.o
;
section .text
global main
extern printf
main:
mov eax, 0xDEADBEEF
push eax
push message
call printf
add esp, 8
ret
message db "Register = %08X", 10, 0
printf
に注意してください cdecl 呼び出し規則を使用するため、後でスタック ポインターを復元する必要があります。つまり、関数に渡されるパラメーターごとに 4 バイトを追加します。
文字列に変換する必要があります。 16 進数について話している場合は、非常に簡単です。任意の数を次のように表すことができます:
0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3
したがって、この番号を取得したら、私が示したように分割し、すべての「セクション」を対応する ASCII に変換する必要があります。
4 つの部分を取得することは、ビット マジックを使用して簡単に実行できます。特に、右シフトを使用して、関心のある部分を最初の 4 ビットに移動し、その結果に 0xf を使用して残りの部分から分離します。これが私の言いたいことです (3 を取りたいとしましょう):
0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003
単一の数値が得られたので、それを ASCII 値に変換する必要があります。数値が 9 以下の場合は、0 の ASCII 値 (0x30) を追加するだけで済みます。9 より大きい場合は、a の ASCII 値 (0x61) を使用する必要があります。
これで、あとはコーディングするだけです:
mov si, ??? ; si points to the target buffer
mov ax, 0a31fh ; ax contains the number we want to convert
mov bx, ax ; store a copy in bx
xor dx, dx ; dx will contain the result
mov cx, 3 ; cx's our counter
convert_loop:
mov ax, bx ; load the number into ax
and ax, 0fh ; we want the first 4 bits
cmp ax, 9h ; check what we should add
ja greater_than_9
add ax, 30h ; 0x30 ('0')
jmp converted
greater_than_9:
add ax, 61h ; or 0x61 ('a')
converted:
xchg al, ah ; put a null terminator after it
mov [si], ax ; (will be overwritten unless this
inc si ; is the last one)
shr bx, 4 ; get the next part
dec cx ; one less to do
jnz convert_loop
sub di, 4 ; di still points to the target buffer
追伸: これが 16 ビット コードであることはわかっていますが、まだ古い TASM を使用しています :P
PPS: これは Intel 構文ですが、AT&T 構文への変換は難しくありません。こちらをご覧ください。