回答
如果您已经在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'或任何其他功能。有评论和解释。 –