Nasm Print One Character at a Time

NASM Print one Character at a Time

One of the reasons it's not printing is because ebx is supposed to hold the value 1 to specify stdin, and another is because sys_write takes a pointer (the address of your string) as an argument, not an actual character value.

Anyway, let me show you a simpler way of structuring your program:

section .data

SYS_EXIT equ 1
SYS_WRITE equ 4
STDOUT equ 1
TRAP equ 0x80
NUL equ 0

hello: db "Hello World",0xA,NUL ; 0xA is linefeed, terminate with NUL

section .text
global _start

_start:
nop ; for good old gdb
mov ecx, hello ; ecx is the char* to be passed to sys_write

read:
cmp byte[ecx], NUL ; NUL indicates the end of the string
je exit ; if reached the NUL terminator, exit

; setup the registers for a sys_write call
mov eax, SYS_WRITE ; syscall number for sys_write
mov ebx, STDOUT ; print to stdout
mov edx, 1 ; write 1 char at a time
int TRAP; ; execute the syscall

inc ecx ; increment the pointer to the next char
jmp read ; loop back to read

exit:
mov eax, SYS_EXIT ; load the syscall number for sys_exit
mov ebx, 0 ; return a code of 0
int TRAP ; execute the syscall

It can be simpler to NUL terminate your string as I did, or you could also do $-hello to get it's length at compile time. I also set the registers up for sys_write at each iteration in the loop (as you do), since sys_write doesn't preserve all the registers.

Can't get single character to print in Linux NASM

This line is incorrect:

mov    ecx, ebx  ; move ebx to print

write (int 80h / eax=4) expects ecx to contain the address of the data to write (see this table). But you're passing the data itself.

In your modified code you're placing the character on the stack and then passing its address in ecx, so that's correct.
However, you've already incremented ecx by the time you get to .printchar. That's why your code doesn't print the first character.

As a side note, your check for even/odd numbers is unncessarily complicated. It could be simplified to just:

test ecx,1      ; set EFLAGS based on ecx AND 1
jnz .printchar

How to print a character in Linux x86 NASM?

ecx should contain a pointer to the start of your char buffer. So you have to have your buffer in memory. You can do the following:

; Print 'A' character 
mov eax, 4 ; __NR_write from asm/unistd_32.h (32-bit int 0x80 ABI)
mov ebx, 1 ; stdout fileno

push 'A'
mov ecx, esp ; esp now points to your char
mov edx, 1 ; edx should contain how many characters to print
int 80h ; sys_write(1, "A", 1)

; return value in EAX = 1 (byte written), or error (-errno)

add esp, 4 ; restore esp if necessary

You can mov byte [esp], 'A' or whatever other address if it's OK to overwrite whatever is on the stack.

Or you can have a character array in section .rodata instead of storing on the fly.


Making a write() system call with the const void *buf arg being some small number (like 'A') will make it return -EFAULT without printing anything. The kernel has to check the pointer anyway, and system calls return an error instead of raising SIGSEGV on bad pointers.

Use strace ./my_program to trace the system calls you actually made, including decoding the return values.

linux nasm print multiple characters

In the first time you enter the Print section, ecx is pointing to the start of the string and you use it to copy a single character to the start of the output string. But a few more instructions down, you overwrite ecx with the pointer to the output string, and never restore it, therefore you never manage to copy and print the rest of the string.

Also, why are you calling write() with a single character string with the aim to loop over it to print the entire string? Why not just pass num directly in instead of copying a single character to output and passing that?

Assembly - Printing a char on graphical mode

Always have Ralf Brown Interrupt List handy.

The service int 10h/AH=0Eh requires the page number in BH and the color to use in BL.

This snippet works

mov ah, 0eh           ;0eh = 14
mov al, 'x'
xor bx, bx ;Page number zero
mov bl, 0ch ;Color is red
int 10h

In text mode the BL is not used, however in graphical mode it is.

Not properly setting it may end up writing "black on black".

Printing a character to standard output in Assembly x86

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


Related Topics



Leave a reply



Submit