To demonstrate the use of ncurses, I took your program example and turned it into a basic use case then developed a demo app. Here's the source. Unfortunately, I run a 32-bit system so if you want to make this into a 64-bit demo.asm, you'll need to visit that tutorial and work your way through and convert this source. I stuck to libraries written in C so that you don't have to worry about calling conventions changing on you, both libc and libncurses are written in C.
; Use Case:
; - create a full screen of a light blue color.
; - put a small rectangle on the screen in yellow.
; - let the user enter 4 digits in black in that rectangle.
; - read the 4 digits from the rectangle.
; Dependencies:
; libc-dev - GNU C library.
; libncurses-dev - Developer's libraries for ncurses.
; Build Process:
; nasm -f elf demo.asm -o demo.o
; gcc -o demo demo.o -lcurses
bits 32
cpu 586
global main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions from the Standard C Library
extern signal
extern atoi
extern exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions from the NCurses Library
extern initscr
extern keypad
extern nonl
extern cbreak
extern echo
extern has_colors
extern start_color
extern init_pair
extern newwin
extern endwin
extern refresh
extern wrefresh
extern wgetnstr
extern wbkgd
extern LINES
extern COLS
%define SIGINT 2 ; defined in signal.h
%define TRUE 1 ; defined in curses.h
%define FALSE 0 ; defined in curses.h
%define COLOR_BLACK 0
%define COLOR_RED 1
%define COLOR_GREEN 2
%define COLOR_YELLOW 3
%define COLOR_BLUE 4
%define COLOR_MAGENTA 5
%define COLOR_CYAN 6
%define COLOR_WHITE 7
%define COLOR_PAIR(n) ((n) << (8))
%define BLACK_ON_BLUE 1
%define BLACK_ON_YELLOW 2
section .data
hWindow: dd 0
hChildWindow: dd 0
szUserInput: db 0, 0, 0, 0, 0
section .text
;; do_init : nothing -> boolean .
;; preform all of the applications initialization.
;; when initialization was successful, hWindow will
;; contain the curses screen handle and the return
;; value will be TRUE. otherwise, it returns FALSE.
do_init:
;; setup an interrupt to terminate
push dword do_exit
push dword SIGINT
call signal
add esp, (2 * 4)
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp eax, 0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
mov eax, FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov dword [hWindow], eax
;; enable keyboard mapping
push dword TRUE
push dword [hWindow]
call keypad
add esp, (2 * 4)
;; tell curses not to translate LF into CRLF on output
call nonl
;; take input chars one at a time, no waiting for newline
call cbreak
;; enable echoing of input
call echo
;; does this system support color terminals?
call has_colors
cmp eax, 0
jne .HasColorSupport
;; No color support, return FALSE
mov eax, FALSE
ret
.HasColorSupport:
call start_color
;; create our color pairs
;; black foreground, blue background
push dword COLOR_BLUE
push dword COLOR_BLACK
push dword BLACK_ON_BLUE
call init_pair
add esp, (3 * 4)
;; black foreground, yellow background
push dword COLOR_YELLOW
push dword COLOR_BLACK
push dword BLACK_ON_YELLOW
call init_pair
add esp, (3 * 4)
;; lets create a child window
push dword 50 ; x value
push dword 10 ; y value
push dword 5 ; 5 columns for 4 digits.
push dword 1 ; 1 line for 1 row of digits.
call newwin
add esp, (4 * 4)
mov [hChildWindow], eax
;; if we reach this point, we have initialized successfully.
mov eax, TRUE
ret
;; do_exit : integer -> nothing .
;; exit to the operating system.
do_exit:
enter 0, 0
;; refresh our screen
call refresh
;; shut down curses
call endwin
;; return to operating system
push dword 0
call exit
add esp, 4
;; we should never reach this point
leave
ret
;; clear_blue : nothing -> nothing .
;; create a full screen of a light blue color.
clear_blue:
;; make our background blue
push dword COLOR_PAIR(BLACK_ON_BLUE)
push dword [hWindow]
call wbkgd
add esp, (2 * 4)
;; refresh our screen
push dword [hWindow]
call wrefresh
add esp, 4
ret
;; draw_child_window : nothing -> nothing .
;; put a small rectangle on the screen in yellow.
draw_child_window:
;; make our background yellow
push dword COLOR_PAIR(BLACK_ON_YELLOW)
push dword [hChildWindow]
call wbkgd
add esp, (2 * 4)
;; refresh our child window
push dword [hChildWindow]
call wrefresh
add esp, 4
ret
;; get_user_input : nothing -> integer .
;; let the user enter 4 digits in black in that rectangle.
get_user_input:
;; get user input
push dword 4 ; 4 characters
push dword szUserInput
push dword [hChildWindow]
call wgetnstr
add esp, (3 * 4)
;; convert string to integer
push dword szUserInput
call atoi
add esp, 4
ret
;; main : integer (string . string) -> integer .
;; our program starts here.
main:
enter 0, 0
call do_init
cmp eax, TRUE
jne .done
;; clear the screen to blue
call clear_blue
;; draw yellow window
call draw_child_window
;; get user input
call get_user_input
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; At this point in our code, the number we ;;
;; entered into our child window is in the ;;
;; EAX register. We can now use it for any- ;;
;; thing we want. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.done:
push dword 0
call do_exit
leave
ret