GNU/Linux >> Znalost Linux >  >> Linux

Jak vytisknout číslo v sestavě NASM?

Pokud již používáte Linux, není třeba provádět konverzi sami. Stačí místo toho použít 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

Všimněte si, že printf používá konvenci volání cdecl, takže musíme poté obnovit ukazatel zásobníku, tj. přidat 4 bajty na parametr předaný funkci.


Musíte jej převést do řetězce; pokud mluvíte o hexadecimálních číslech, je to docela snadné. Libovolné číslo lze znázornit takto:

0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3

Takže když máte toto číslo, musíte ho rozdělit, jak jsem ukázal, a poté převést každou "sekci" na její ekvivalent ASCII.
Získání čtyř částí se snadno provede trochou magie, zejména posunutím doprava, abyste přesunuli část, která nás zajímá, v prvních čtyřech bitech A výsledek s 0xf, abyste ji izolovali od zbytku. Zde je to, co mám na mysli (protože chceme vzít 3):

0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003

Nyní, když máme jediné číslo, musíme ho převést na jeho ASCII hodnotu. Pokud je číslo menší nebo rovno 9, můžeme přidat pouze ASCII hodnotu 0 (0x30), pokud je větší než 9, musíme použít ASCII hodnotu a (0x61).
Tady to je, teď to jen musíme nakódovat:

    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

PS: Vím, že se jedná o 16bitový kód, ale stále používám starý TASM :P

PPS: toto je syntaxe Intelu, převod na syntaxi AT&T však není obtížný, podívejte se sem.


Linux
  1. Jak pěkně vytisknout soubor JSON v terminálu Linux

  2. Jak zrušit příkaz pro rozbalení?

  3. Jak vytisknu obsah úloh?

  1. Jak zvýšit limit počtu otevřených souborů v Linuxu

  2. Jak zvýšit počet inodů v souborovém systému Ext4?

  3. Jak vytisknout proměnnou s vycpaným zarovnáním na střed?

  1. Jak vytisknout řádky číslo 15 a 25 z každých 50 řádků?

  2. Jak zkontrolovat, zda Bash může tisknout barvy?

  3. Jak vytisknout pthread_t