I'm learning the NASM assembler and I have being stuck at the moment with handling the linefeed.
How do I print the linefeed? I'll show you. But, before I show it, it's important to tell you about my platform:
$ uname -a
Linux 4.4.0-97-generic #120-Ubuntu SMP Tue Sep 19 17:28:18 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID : Ubuntu
Description : Ubuntu 16.04.3 LTS
Release : 16.04
Codename : xenial
My functions, which I have prepared for the learning:
sprint:
push rdx
push rbx
push rax
push rcx
mov rax, rcx
pop rcx
jmp next_char
ret
sprint_syscall:
mov rbx, 1
mov rax, 4
int 80h
pop rax
pop rbx
pop rdx
ret
sprint_linefeed:
call sprint
push rcx
mov rcx, 0Ah
push rcx
mov rcx, rsp
call sprint
pop rcx
pop rcx
ret
next_char:
cmp byte [rax], 0
jz count_length
inc rax
jmp next_char
count_length:
sub rax, rcx
mov rdx, rax
jmp sprint_syscall
quit:
push rbx
push rax
mov rbx, 0
mov rax, 1
int 80h
pop rax
pop rbx
ret
Main app, which may use one of the given functions:
%include 'functions.asm'
SECTION .data
msgFirst db "Hello World!", 0h
msgSecond db "Another string.", 0h
SECTION .text
global _start
_start:
mov rcx, msgFirst
call sprint_linefeed
mov rcx, msgSecond
call sprint_linefeed
call quit
All is compiling fine and works pretty too. If to compile/link with:
nasm -g -f elf64 -l main.lst main.asm -o main.o && ld main.o -o main
And then execute the compiled app, we're able to see:
Hello World!Another string
As you can see, there weren't any linefeed, despite on calling the sprint_linefeed
function, which uses the next instructions for printing the linefeed:
sprint_linefeed:
call sprint
push rcx ; push rcx onto the stack to preserve it
mov rcx, 0Ah ; move 0Ah into rcx, 0Ah is the ASCII char for a linefeed
push rcx ; push the linefeed char onto the stack
mov rcx, rsp ; move the address of the pointer into rcx for the 'sys_write' syscall
call sprint
pop rcx ; remove the linefeed char from the stack
pop rcx ; restore the original value of rcx
ret
So, the explanation of my actions refers to sprint()
call for the given string and then pushing the 0Ah
char onto stack. Later, I'm getting the pointer from the RSP-register to call the sprint()
function again.
It was done, because the SYS_WRITE
syscall requires the pointer to print the give string (http://fresh.flatassembler.net/lscr/data/004.html).
If to add the OAh
char to the string declaration:
SECTION .data
msgFirst db "Hello World!", 0Ah, 0h
Calling the same function, but with the different string value, gives us the awaited result, but it makes NO sense, because sprint_linefeed()
was defined to pass the declaration of the redundant ASCII-char.
What should I fix in my source-code to make sprint_linefeed()
work fine?