回答
如果您已經在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 calling convention所以我們需要事後恢復堆棧指針,即每增加傳遞給函數的參數4個字節。
謝謝,它似乎是我在尋找的東西。你知道它是否也適用於Mac OS X嗎? – AR89
如何在64編譯它-bit? –
@FigenGüngörhttp://stackoverflow.com/a/32853546/895245 –
你必須將它轉換成一個字符串;如果你在談論十六進制數字,那很簡單。任何數字都代表這樣說:
0xa31f = 0xf * 16^0 + 0x1 * 16^1 + 3 * 16^2 + 0xa * 16^3
所以,當你有這個號碼,你必須把它分解像我展示之後每「節」轉換爲字符的ASCII等價的。獲得這四個部分很容易完成,具有一些魔力,特別是在右前移四個部分,然後用0xf移動我們感興趣的部分,並將結果與其餘部分隔離。這裏就是我的意思(soppose我們想拿3):
0xa31f -> shift right by 8 = 0x00a3 -> AND with 0xf = 0x0003
現在,我們有我們必須把它轉換成字符的ASCII值單號。如果數字小於或等於9,我們可以添加0的ASCII值(0x30),如果它大於9,我們必須使用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
PS:我知道這是16位代碼,但我仍然使用舊的TASM:P
PPS:這是英特爾語法,轉換爲AT & T語法雖然不難,但請看here。
的Linux的x86-64與printf的
extern printf, exit
section .data
format db "%x", 10, 0
section .text
global main
main:
sub rsp, 8
mov rsi, 0x12345678
mov rdi, format
xor rax, rax
call printf
mov rdi, 0
call exit
然後:
nasm -f elf64 main.asm
gcc main.o
./a.out
System V的AMD64 ABI調用約定的 「硬點」:
sub rsp, 8
: How to write assembly language hello world program for 64 bit Mac OS X using printf?mov rax, 1
:Why is %eax zeroed before a call to printf?
如果你想不十六進制的C庫:https://stackoverflow.com/a/32756303/895245
我是比較新的組件,而這顯然不是最好的解決辦法,但 它的工作。主要功能是_iprint,它首先檢查eax中的 號碼是否爲負值,如果是,則打印負號,然後通過調用每個數字的 調用函數_dprint打印單個號碼來執行 。這個想法如下,如果我們有512比它等於:512 =(5 * 10 + 1)* 10 + 2 = Q * 10 + R,所以我們可以找到一個數字的最後一位數字除以10,和 得到提醒R,但如果我們在一個循環中執行比數字將在 倒序,所以我們使用堆棧推動它們,然後當 寫入他們的標準輸出他們彈出正確的順序。
; Build : nasm -f elf -o baz.o baz.asm
; ld -m elf_i386 -o baz baz.o
section .bss
c: resb 1 ; character buffer
section .data
section .text
; writes an ascii character from eax to stdout
_cprint:
pushad ; push registers
mov [c], eax ; store ascii value at c
mov eax, 0x04 ; sys_write
mov ebx, 1 ; stdout
mov ecx, c ; copy c to ecx
mov edx, 1 ; one character
int 0x80 ; syscall
popad ; pop registers
ret ; bye
; writes a digit stored in eax to stdout
_dprint:
pushad ; push registers
add eax, '0' ; get digit's ascii code
mov [c], eax ; store it at c
mov eax, 0x04 ; sys_write
mov ebx, 1 ; stdout
mov ecx, c ; pass the address of c to ecx
mov edx, 1 ; one character
int 0x80 ; syscall
popad ; pop registers
ret ; bye
; now lets try to write a function which will write an integer
; number stored in eax in decimal at stdout
_iprint:
pushad ; push registers
cmp eax, 0 ; check if eax is negative
jge Pos ; if not proceed in the usual manner
push eax ; store eax
mov eax, '-' ; print minus sign
call _cprint ; call character printing function
pop eax ; restore eax
neg eax ; make eax positive
Pos:
mov ebx, 10 ; base
mov ecx, 1 ; number of digits counter
Cycle1:
mov edx, 0 ; set edx to zero before dividing otherwise the
; program gives an error: SIGFPE arithmetic exception
div ebx ; divide eax with ebx now eax holds the
; quotent and edx the reminder
push edx ; digits we have to write are in reverse order
cmp eax, 0 ; exit loop condition
jz EndLoop1 ; we are done
inc ecx ; increment number of digits counter
jmp Cycle1 ; loop back
EndLoop1:
; write the integer digits by poping them out from the stack
Cycle2:
pop eax ; pop up the digits we have stored
call _dprint ; and print them to stdout
dec ecx ; decrement number of digits counter
jz EndLoop2 ; if it's zero we are done
jmp Cycle2 ; loop back
EndLoop2:
popad ; pop registers
ret ; bye
global _start
_start:
nop ; gdb break point
mov eax, -345 ;
call _iprint ;
mov eax, 0x01 ; sys_exit
mov ebx, 0 ; error code
int 0x80 ; край
你可以'添加'0''並將你的數字存儲在緩衝區中,當你產生它們時,使用'dec'將指針向下移動。當你完成後,你有一個指向你存儲的最後一位數字的指針,所以你可以將它傳遞給'sys_write()'(以及數字計數)。這比爲每個字節進行單獨的系統調用,並沒有真正需要更多的代碼。很容易分配足夠長的緩衝區以保存最長的數字串,並從最後開始,因爲您知道2^32有多少個小數位。 –
相關:我寫了一個整數 - >字符串循環作爲[擴展精度斐波那契代碼 - 高爾夫答案](https://codegolf.stackexchange.com/questions/133618/extreme-fibonacci/135618#135618)的一部分。請參閱'.toascii_digit:'循環。當然,這是針對大小進行優化的,所以它使用了一個緩慢的'div' [而不是一個多重技巧](https://stackoverflow.com/questions/41183935/why-does-gcc-use-multiplication-by-a-陌生的號碼,在-實施-整數迪維)。 –
謝謝你肯定比調用每個數字的sys_write更好:) – baz
- 1. 如何在NASM中打印64位數字?
- 2. 如何打印NASM中的8位值
- 3. 在NASM彙編中打印出大於9的數字
- 4. NASM with Bochs - Assembly - 打印字符串
- 5. 使用printf asm nasm打印整行數組在單行上
- 6. 在數組中向後打印數字
- 7. 如何在javascript中打印字符串(數字)打印
- 8. 如何在組件中打印DWord?
- 9. 如何在FireFox3中打印Flex組件?
- 10. NASM打印到下一行
- 11. 如何在gdb中打印Java數組?
- 12. 如何在數組中打印對象?
- 13. 如何在GDB中打印Fortran數組?
- 14. 如何在javascript中打印php數組
- 15. 如何在java中打印數組?
- 16. 如何在AutoHotkey中打印數組?
- 17. 如何在字符數組中打印字符而不重複?
- 18. 如何打印Wpf組件
- 19. 如何打印ExtJS組件?
- 20. 在C中,如何從多維數組中打印字符串?
- 21. 如何從字符數組中打印字符和整數
- 22. 如何漂亮地打印字節數組和字符數組?
- 23. C通用打印數組函數 - 打印字符串數組
- 24. 在nasm 64bit Linux機器上打印
- 25. 如何打印空數組
- 26. 如何打印數組?
- 27. 如何打印數組值?
- 28. 如何在組件中打印兩次字符串
- 29. 如何在Matlab中將數組打印到.txt文件中?
- 30. 如何在java中打印2d數組中的文本文件?
請指定程序運行的操作系統。 –
相關:[將整數轉換爲棧中緩衝區中的ASCII十進制字符串並使用Linux'write'系統調用](https://stackoverflow.com/a/46301894/224132)打印,而不是使用'printf'或任何其他功能。有評論和解釋。 –