GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana cara mencetak nomor di perakitan NASM?

Jika Anda sudah menggunakan Linux, Anda tidak perlu melakukan konversi sendiri. Cukup gunakan printf sebagai gantinya:

;
; 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

Perhatikan bahwa printf menggunakan konvensi pemanggilan cdecl sehingga kita perlu memulihkan penunjuk tumpukan setelahnya, yaitu menambahkan 4 byte per parameter yang diteruskan ke fungsi.


Anda harus mengonversinya dalam sebuah string; jika Anda berbicara tentang angka hex itu cukup mudah. Angka apa pun dapat direpresentasikan dengan cara ini:

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

Jadi, ketika Anda memiliki nomor ini, Anda harus membaginya seperti yang telah saya tunjukkan, lalu ubah setiap "bagian" menjadi ASCII yang setara.
Mendapatkan empat bagian mudah dilakukan dengan sedikit keajaiban, khususnya dengan pergeseran kanan untuk memindahkan bagian yang kita minati pada empat bit pertama kemudian DAN hasilnya dengan 0xf untuk mengisolasinya dari yang lain. Inilah yang saya maksud (jadi kita ingin mengambil 3):

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

Sekarang kita memiliki satu nomor, kita harus mengubahnya menjadi nilai ASCII-nya. Jika angkanya lebih kecil atau sama dengan 9 kita cukup menambahkan nilai ASCII 0 (0x30), jika lebih besar dari 9 kita harus menggunakan nilai ASCII a (0x61).
Ini dia, sekarang kita tinggal mengkodekannya:

    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: Saya tahu ini kode 16 bit tapi saya masih menggunakan TASM lama :P

PPS: ini adalah sintaks Intel, mengonversi ke sintaks AT&T tidaklah sulit, lihat di sini.


Linux
  1. Cara mencetak pthread_t

  2. Bagaimana cara mendapatkan ps untuk mencetak grup?

  3. Bagaimana cara mencetak pesan ke stderr di Go?

  1. Cara Meningkatkan Jumlah Batas File Terbuka di Linux

  2. Cara Mencetak File JSON dengan Cantik di Terminal Linux

  3. Bagaimana Cara Meningkatkan Jumlah Inode Dalam Sistem File Ext4?

  1. Bagaimana Cara Mencetak Variabel Dengan Perataan Pusat Empuk?

  2. Bagaimana Cara Mencetak Baris Nomor 15 Dan 25 Dari Setiap 50 Baris?

  3. Bagaimana Cara Memeriksa Apakah Bash Dapat Mencetak Warna?