Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing a character to standard output in Assembly x86

I'm a little confused about how to print a character to the screen using Assembly. The architecture is x86 (linux). Is it possible to call one of the C functions or is there a simpler way? The character I want to output is stored in a register.

Thanks!

like image 382
user973758 Avatar asked Nov 20 '11 12:11

user973758


People also ask

What does $$ mean in x86 assembly?

$ is used to refer to the current address and $$ is used to refer to the address of the start of current section in assembly.

What does %d do in assembly?

"%d", 10, 0 are the bytes to dump into the stream. The first is an ascii string, which dumps two bytes (the characters '%' and 'd'), 10 is a newline character ( \n in C), and 0 is a null byte.

Can you print in assembly?

Assembly language has no direct means of printing anything. Your assembler may or may not come with a library that supplies such a facility, otherwise you have to write it yourself, and it will be quite a complex function.

What does Movslq mean in assembly?

MOVSLQ is move and sign-extend a value from a 32-bit source to a 64-bit destination.


2 Answers

In the interest of completeness, here is how to do it without C.

Using DOS interrupts

AH = 02h -WRITE CHARACTER TO STANDARD OUTPUT

Writes character in DL. I haven't tested this myself. in NASM syntax something like

mov ah, 02h
int 21h

x86-32 Linux write syscall

write requires the address of your string. The easiest way I know of is to push your character on the stack.

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

Similar to above, but the call number is now 1, syscall instead of int $0x80, and the calling convention registers are different.

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 
like image 71
qwr Avatar answered Sep 20 '22 05:09

qwr


Sure, you can use any normal C function. Here's a NASM example that uses printf to print some output:

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

If you only want to print a single character, you could use putchar:

push eax
call putchar

If you want to print out a number, you could do it like this:

mov ebx, 8
push ebx
push message
call printf
...    
message db 'The number is: %d', 10, 0
like image 40
Martin Avatar answered Sep 21 '22 05:09

Martin