GNU/Linux >> Linux Esercitazione >  >> Linux

Come stampare un numero nell'assemblea NASM?

Se sei già su Linux, non è necessario eseguire la conversione da solo. Usa invece 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

Nota che printf usa la convenzione di chiamata cdecl quindi dobbiamo ripristinare il puntatore dello stack in seguito, ovvero aggiungere 4 byte per parametro passato alla funzione.


Devi convertirlo in una stringa; se stai parlando di numeri esadecimali è abbastanza facile. Qualsiasi numero può essere rappresentato in questo modo:

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

Quindi, quando hai questo numero devi dividerlo come ho mostrato, quindi convertire ogni "sezione" nel suo equivalente ASCII.
Ottenere le quattro parti è facile con un po' di magia, in particolare con uno spostamento a destra per spostare la parte che ci interessa nei primi quattro bit, quindi E il risultato con 0xf per isolarlo dal resto. Ecco cosa intendo (supponiamo di voler prendere il 3):

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

Ora che abbiamo un singolo numero dobbiamo convertirlo nel suo valore ASCII. Se il numero è minore o uguale a 9 possiamo semplicemente aggiungere il valore ASCII di 0 (0x30), se è maggiore di 9 dobbiamo usare il valore ASCII di a (0x61).
Eccolo, ora dobbiamo solo codificarlo:

    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: So che questo è un codice a 16 bit ma uso ancora il vecchio TASM :P

PPS: questa è la sintassi Intel, tuttavia la conversione nella sintassi AT&T non è difficile, guarda qui.


Linux
  1. Come stampare una variabile con allineamento centrale imbottito?

  2. Come verificare se Bash può stampare i colori?

  3. Come stampare pthread_t

  4. Come ottenere ps per stampare il gruppo?

  5. Come annullare il comando di decompressione?

Come trovare il numero di porta di un servizio in Linux

Come spostare un gran numero di file in Linux

Come copiare un gran numero di file in Linux

Come controllare il numero di versione e il nome in codice di Linux Mint

Come eseguire il ping di un numero di porta in Linux

Come eseguire il ping di un numero di porta specifico