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
Type Null Character in Terminal
Jni Issue on Linux: Cannot Open Shared Object File
Assembly Linux System Calls VS Assembly Os X System Calls
Fatal: Bad Config File Line 1 in /Home/Trx/.Gitconfig
How to Find the Particular Text Stored in the File "Data.Txt" and It Occurs Only Once
How Do Programs Communicate with Each Other
Why Does This Movq Instruction Work on Linux and Not Osx
Linux /Bin/Sh Check If String Contains X
How to Install Visual Studio 2015 in Ubuntu
How to Find List of Odbc Drivers Installed on Linux
Dlopen Failed: Cannot Open Shared Object File: No Such File or Directory
Converting a Pcap Trace to Netflow Format
How to Count Most Occuring Sequence of 3 Letters Within a Word with a Bash Script
Pkill Returns 255 in Combination with Another Command via Remote Ssh
Linux/Module.H No Such File or Directory
Synchronizing Four Shell Scripts to Run One After Another in Unix