flat assembler
Message board for the users of flat assembler.

Index > Linux > ANSI Escape Sequences

Author
Thread Post new topic Reply to topic
chastitywhiterose



Joined: 13 Oct 2025
Posts: 45
chastitywhiterose 01 Jan 2026, 05:30
Here it is. My most recent project since I perfected chastehex. This small program allows moving the cursor anywhere in the terminal. It took me awhile to figure out how to use the escape codes to position the cursor. As it turns out, I simply had to write my own implementation of strcpy along with my own intstr function to build the escape sequence string with the right information.

It is just a start, but since this works in a Linux terminal, it means I could theoretically start designing simple games in Linux x86 assembly language. I wrote some other games in C before but doing it in assembly would be a first time. I will probably make small games within my skill level based on this foundation.

Code:
format ELF executable
entry main

include 'chastelib32.asm'
include 'ansi.asm'

main: ; the main function of our assembly function, just as if I were writing C.

keyloop:

mov [radix],16 ; Choose radix for integer output!
mov [int_width],8
mov [int_newline],0 ;disable automatic printing of newlines after putint

;first clear the screen
mov eax, ansi_clear
call putstring

;reset cursor to home AKA top left of screen
mov eax,ansi_home
call putstring

mov eax,prefix_k
call putstring
mov eax,[key]
call putint
call putline

mov eax,prefix_x
call putstring
mov eax,[x]
call putint
call putspace

mov eax,prefix_y
call putstring
mov eax,[y]
call putint
call putline

mov eax,msg
call putstring

cmp [showhelp],0
jz help_skip

print_help:
mov eax,help
call putstring
call putline

help_skip:

;move the cursor with the function I wrote in ansi.asm
call move_cursor


call read_key

cmp [key],0x68
jz toggle_help

cmp [key],0x41
jz key_up
cmp [key],0x42
jz key_down

cmp [key],0x44
jz key_left
cmp [key],0x43
jz key_right

jmp keyloop_end

;conditional blocks based on input
key_up:
dec [y]
jmp keyloop_end
key_down:
inc [y]
jmp keyloop_end

key_left:
dec [x]
jmp keyloop_end
key_right:
inc [x]
jmp keyloop_end

toggle_help:
xor [showhelp],1
jmp keyloop_end

keyloop_end:
cmp [key],'q' ;loop will go until q is pressed
jnz keyloop

main_end:
mov eax, 1  ; invoke SYS_EXIT (kernel opcode 1)
mov ebx, 0  ; return 0 status on exit - 'No Errors'
int 80h

; string variables to display useful information

msg db "Press q to quit, h for help", 0Ah,0     ; assign msg variable with your message string
help db "This program operates the terminal by using ANSI escape sequences. "
     db "The arrow keys move the cursor around the terminal. "
     db "That is all there is for now, but it is possible that with more code, this could make a small game."
     db "But don't forget, this program only works if the Linux command `stty cbreak` is run first."
     db 0xA,"This turns off line buffering so that each key operates immediately."
     db 0xA,"You can turn this help message on or off with the h key again.",0
showhelp dd 0
    


Description: A new header file I wrote which uses clever string building for a cursor movement function and some other things which are not used in this particular program.
Download
Filename: ansi.asm
Filesize: 3.15 KB
Downloaded: 16 Time(s)

Description: My string and integer output functions that are required for everything.
Download
Filename: chastelib32.asm
Filesize: 5.99 KB
Downloaded: 15 Time(s)

Post 01 Jan 2026, 05:30
View user's profile Send private message Send e-mail Reply with quote
Jessé



Joined: 03 May 2025
Posts: 71
Location: Brazil
Jessé 03 Jan 2026, 23:29
Seeing 'ANSI' and 'Linux' in the same paragraph is weird, but, anyways...
Have you ever heard of libncurses?
I think is the best way to what you are looking for.
It has even mouse support, and many applications use it, like, htop, top, nvtop, nano, etc..
Provides a blank terminal canvas, with even (abstraction of) windows!
Try it, I think you'll never regret. To me it take half a day to learn about, and another one to do something useful with it (a digital clock, with sizeable digits).
I don't know if still has 32-bit support, perhaps you'll need to go 64-bit to use it.
Post 03 Jan 2026, 23:29
View user's profile Send private message Visit poster's website Reply with quote
chastitywhiterose



Joined: 13 Oct 2025
Posts: 45
chastitywhiterose 04 Jan 2026, 19:31
I am aware of ncurses. I have used it before in C but don't have the first clue about how to use external libraries in Assembly with FASM. It might be interesting but the ability to use escape sequences to move the cursor around and print at different places on the screen removes the dependence on a library like ncurses, which probably uses them under the hood anyway.
Post 04 Jan 2026, 19:31
View user's profile Send private message Send e-mail Reply with quote
Jessé



Joined: 03 May 2025
Posts: 71
Location: Brazil
Jessé 04 Jan 2026, 19:49
Hmm, I understood.
To use libraries, you will have to use 'extrn' directive to import functions, I guess, for fasm (1), and use external linker (like 'ld') to link the '.o' object files where you append the library names.
I'm on fasm2, so, I cannot not guarantee that it is the same, but, probably it is.
Post 04 Jan 2026, 19:49
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 826
Location: Russian Federation, Sochi
ProMiNick 04 Jan 2026, 21:35
To use libraries in linux is similar to windows - func names must be listed in stringtable of elf. Table of pointers to that functions is placed after last (counted initialized & reserved ones) byte by default. That is simplest way to make elf executable with dinamicaly loaded *.so. Everything without garbage as external linker.
Post 04 Jan 2026, 21:35
View user's profile Send private message Send e-mail Reply with quote
Jessé



Joined: 03 May 2025
Posts: 71
Location: Brazil
Jessé 05 Jan 2026, 10:52
Take this example on how to use external libraries:

Code:
format ELF64 

extrn printf
extrn __libc_start_main
extrn stdout
public Start

section '.text' executable

        align 4
        Start:          endbr64
                        push        rsp
                        mov         r9, rdx
                        xor         r8d, r8d
                        xor         ecx, ecx
                        lea         rdx, [rsp+16]
                        mov         esi, [rsp+8]
                        lea         rdi, [main]
                        jmp         plt __libc_start_main
                        
        align 4
        main:           endbr64
                        enter       0, 0
                        lea         rdi, [msg0]
                        xor         al, al
                        call        plt printf
                        
                        leave
                        xor         eax, eax
                        ret
                        
section '.data' writeable

        msg0:           db 'This is a fasm 1 program, compiled in'
                        db ' a traditional way!',10,0

    


To compile:
Quote:

fasm example.asm
ld -o example example.o -e Start -lc --dynamic-linker=/lib64/ld-linux-x86-64.so.2
#run it with:
./example

-lc -> to link with libc;
-lpthread -> to link with libpthread;
-lncurses -> to link with lincurses
And so on...

Optionally, you can optimize the final executable size with:
Quote:

strip --strip-unneeded example


I've tested this with fasm 1 and it worked.
Post 05 Jan 2026, 10:52
View user's profile Send private message Visit poster's website Reply with quote
Jessé



Joined: 03 May 2025
Posts: 71
Location: Brazil
Jessé 05 Jan 2026, 11:01
The only drawback I had with fasm 1 (instead of fasm2) is that I couldn't find a way to access using GOT. But I had not searched deeper.

Example:

'mov rdi, [got stdout]'

Simply does not work with fasm 1, but:

'mov rdi, [got.stdout]'

Works fine with fasm2.
Post 05 Jan 2026, 11:01
View user's profile Send private message Visit poster's website Reply with quote
chastitywhiterose



Joined: 13 Oct 2025
Posts: 45
chastitywhiterose 06 Jan 2026, 01:53
I have no idea how any of that works but maybe I can play around with it and see if it lets me do some combinations of C and Assembly. Perhaps it could be used to write more portable code between operating systems.
Post 06 Jan 2026, 01:53
View user's profile Send private message Send e-mail Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.