在Assembly x86中将字符打印到标准输出

时间:2011-11-20 12:55:08

标签: assembly printing x86

我对如何使用Assembly将字符打印到屏幕感到困惑。该架构是x86(linux)。可以调用其中一个C函数还是有更简单的方法?我想输出的字符存储在寄存器中。

谢谢!

3 个答案:

答案 0 :(得分:5)

当然,您可以使用任何正常的C函数。这是一个使用printf打印输出的NASM示例:

;
; assemble and link with:
; nasm -f elf test.asm && gcc -m32 -o test test.o
;
section .text

extern printf   ; If you need other functions, list them in a similar way

global main

main:

    mov eax, 0x21  ; The '!' character
    push eax
    push message
    call printf
    add esp, 8     ; Restore stack - 4 bytes for eax, and 4 bytes for 'message'
    ret

message db 'The character is: %c', 10, 0

如果您只想打印单个字符,可以使用putchar

push eax
call putchar

如果你想打印一个数字,你可以这样做:

mov ebx, 8
push ebx
push message
call printf
...    
message db 'The number is: %d', 10, 0

答案 1 :(得分:3)

为了完整起见,这是不使用C的方法。

使用DOS中断

AH = 02h -WRITE CHARACTER TO STANDARD OUTPUT

DL中写入字符。我自己还没有测试过。在NASM语法中,例如

mov ah, 02h
int 21h

x86-32 Linux write syscall

write需要您的字符串地址。我知道的最简单的方法是将您的角色压入堆栈。

push    $0x21       # '!'
mov     $4, %eax    # sys_write call number 
mov     $1, %ebx    # write to stdout (fd=1)
mov     %esp, %ecx  # use char on stack
mov     $1, %edx    # write 1 char
int     $0x80   
add     $4, %esp    # restore sp 

Info on register order

x86-64 Linux write syscall

类似于上面,但是呼叫号码现在为1,syscall而不是int $0x80,并且呼叫约定寄存器不同。

push    $0x21       # '!'
mov     $1, %rax    # sys_write call number 
mov     $1, %rdi    # write to stdout (fd=1)
mov     %rsp, %rsi  # use char on stack
mov     $1, %rdx    # write 1 char
syscall   
add     $8, %rsp    # restore sp 

答案 2 :(得分:0)

调用putchar(3)是最简单的方法。只需将char的值移动到rdi寄存器(x86-64或x86的edi),然后调用putchar

E.g。 (对于x86-64):

asm("movl $120, %rdi\n\t"
    "call putchar\n\t");

将打印x到标准输出。