GNU/Linux >> Linux の 問題 >  >> Linux

アセンブリNASMで数値を出力するには?

すでに 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 構文への変換は難しくありません。こちらをご覧ください。


Linux
  1. Ext4ファイルシステムのiノードの数を増やす方法は?

  2. パッド入りの中央揃えで変数を印刷するにはどうすればよいですか?

  3. Goでstderrにメッセージを出力するにはどうすればよいですか?

  1. Linuxで開くファイルの数の制限を増やす方法

  2. LinuxターミナルでJSONファイルをきれいに印刷する方法

  3. at ジョブの内容を印刷するにはどうすればよいですか?

  1. 各50行から15行目と25行目を印刷する方法は?

  2. Bashが色を印刷できるかどうかを確認する方法は?

  3. pthread_t を出力する方法