; Source name : VIDLIB.ASM
; Compiled name : VIDLIB.OBJ
; Code model: : Real mode segmented model
; Version : 1.0
; Created date : 9/12/1999
; Last update : 9/12/1999
; Author : Jeff Duntemann
; Description : A simple example of a separately assembled module
; containing utility procedures for controlling the
; PC display. Assembled using NASM 0.98. DOS programs
; can link to these routines by declaring them EXTERN
; and then linking the program .OBJ to VIDLIB.OBJ using
; a linker like ALINK.
;----------------------------|
; BEGIN DATA SEGMENT |
;----------------------------|
SEGMENT .data
;Note that the following items are defined externally to this module, and
; for certain routines in this module to function these data items must
; be linked in from a properly assembled external module.
EXTERN CRLF,LRXY
;----------------------------|
; BEGIN CODE SEGMENT |
;----------------------------|
SEGMENT .text ; This segment may be accessed externally
; Note that the following items are GLOBAL, and may be accessed by
; external files that declare them EXTERN.
GLOBAL GotoXY,ClrScr,ClrWin,ScrlWin,VIDEO6
GLOBAL Write,Writeln
;---------------------------------------------------------------
; GOTOXY -- Positions the hardware cursor to X,Y
; Last update 9/12/99
;
; 1 entry point:
;
; GotoXY:
; Caller must pass:
; DL: X value These are both 0-based; i.e., they
; DH: Y value assume a screen 24 by 79, not 25 by 80
; Action: Moves the hardware cursor to the X,Y position
; loaded into DL and H.
;---------------------------------------------------------------
GotoXY:
sub esp, 16
mov edi, esp
mov byte [edi], 27 ; "ESC"
inc edi
mov byte [edi], '['
inc edi
mov al, dh
call al2dec
mov byte [edi], ';'
inc edi
mov al, dl
call al2dec
mov byte [edi], 'H'
inc edi
mov byte [edi], 0
mov edx, esp
call Write
add esp, 16
ret ; Return to the caller
al2dec:
xor ecx, ecx
mov bl, 10
.pushloop:
mov ah, 0
div bl
push eax
inc ecx
cmp al, 0
jnz .pushloop
.poploop:
pop eax
mov al, ah
add al, '0'
stosb
loop .poploop
ret
;---------------------------------------------------------------
; CLRSCR -- Clears or scrolls screens or windows
; Last update 9/12/99
;
; 4 entry points:
;
; ClrScr:
; No values expected from caller
; Action: Clears the entire screen to blanks with 07H as
; the display attribute
;
; ClrWin:
; Caller must pass:
; CH: Y coordinate, upper left corner of window
; CL: X coordinate, upper left corner of window
; DH: Y coordinate, lower right corner of window
; DL: X coordinate, lower right corner of window
; Action: Clears the window specified by the caller to
; blanks with 07H as the display attribute
;
; ScrlWin:
; Caller must pass:
; CH: Y coordinate, upper left corner of window
; CL: X coordinate, upper left corner of window
; DH: Y coordinate, lower right corner of window
; DL: X coordinate, lower right corner of window
; AL: number of lines to scroll window by (0 clears it)
; Action: Scrolls the window specified by the caller by
; the number of lines passed in AL. The blank
; lines inserted at screen bottom are cleared
; to blanks with 07H as the display attribute
;
; VIDEO6:
; Caller must pass:
; CH: Y coordinate, upper left corner of window
; CL: X coordinate, upper left corner of window
; DH: Y coordinate, lower right corner of window
; DL: X coordinate, lower right corner of window
; AL: number of lines to scroll window by (0 clears it)
; BH: display attribute for blanked lines (07H is "normal")
; Action: Generic access to BIOS VIDEO service 6. Caller
; must pass ALL register parameters as shown above
;---------------------------------------------------------------
ClrScr:
sub esp, 16
mov edi, esp
mov byte [edi], 27
inc edi
mov byte [edi], '['
inc edi
mov byte [edi], '2'
inc edi
mov byte [edi], 'J'
inc edi
mov byte [edi], 0
mov edx, esp
call Write
add esp, 16
ret
mov CX,0 ; Upper left corner of full screen
mov DX,word [LRXY] ; Load lower-right XY coordinates into DX
ClrWin: mov AL,0 ; 0 specifies clear entire region
ScrlWin: mov BH,07H ; Specify "normal" attribute for blanked line(s)
VIDEO6: mov AH,06H ; Select VIDEO service 6: Initialize/Scroll
int 10H ; Call VIDEO
ret ; Return to the caller
;---------------------------------------------------------------
; WRITE -- Displays information to the screen via DOS
; service 9: Print String
; Last update 9/12/99
;
; 1 entry point:
;
; Write:
; Caller must pass:
; DS: The segment of the string to be displayed
; DX: The offset of the string to be displayed
; String must be terminated by "$"
; Action: Displays the string at DS:DX up to the "$" marker
;---------------------------------------------------------------
Write:
mov ecx, edx
or edx, byte -1
.getlen:
inc edx
cmp byte [ecx + edx], 0
jnz .getlen
mov ebx, 1
mov eax, 4
int 80h
ret
;---------------------------------------------------------------
; WRITELN -- Displays information to the screen via DOS
; service 9 and issues a newline
; Last update 9/12/99
;
; 1 entry point:
;
; Writeln:
; Caller must pass:
; DS: The segment of the string to be displayed
; DX: The offset of the string to be displayed
; String must be terminated by "$"
; Action: Displays the string at DS:DX up to the "$" marker
; marker, then issues a newline. Hardware cursor
; will move to the left margin of the following
; line. If the display is to the bottom screen
; line, the screen will scroll.
; Calls: Write
;---------------------------------------------------------------
Writeln:
call Write ; Display the string proper through Write
mov eDX,CRLF ; Load address of newline string to DS:DX
call Write ; Display the newline string through Write
ret ; Return to the caller
But you will find that running a 64-bit computerDo you have evidence of this, or is it an assumption? True of all programs, or just certain programs? What would make a good test case?
with a 64-bit OS runs much faster,
grep __NR $(locate unistd_64.h) | grep define | sed -e 's/\#/\%/' -e 's/__NR_/SYS_/' > unistd_64.inc
$ grep __NR $(locate unistd_64.h) | grep define | sed -e 's/\#/\%/' -e 's/__NR_/SYS_/' > unistd_64.inc
$ ls -a
. .. unistd_64.inc
$ head unistd_64.inc
%define SYS_read 0
%define SYS_write 1
%define SYS_open 2
%define SYS_close 3
%define SYS_stat 4
%define SYS_fstat 5
%define SYS_lstat 6
%define SYS_poll 7
%define SYS_lseek 8
%define SYS_mmap 9
$ man mmap
MMAP(2) Linux Programmer's Manual MMAP(2)
NAME
mmap, munmap - map or unmap files or devices into memory
SYNOPSIS
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
See NOTES for information on feature test macro requirements.
DESCRIPTION
mmap() creates a new mapping in the virtual address space of the call?
ing process. The starting address for the new mapping is specified in
addr. The length argument specifies the length of the mapping.
If addr is NULL, then the kernel chooses the address at which to create
the mapping; this is the most portable method of creating a new map?
ping. If addr is not NULL, then the kernel takes it as a hint about
where to place the mapping; on Linux, the mapping will be created at a
Manual page mmap(2) line 1 (press h for help or q to quit)
mov dl, [x_pos]
mov dh, [y_pos]
call gotoxy
The x- and y- in dx is copied from the bios interrupt - you could do it a different way...;OBJ : Display a character
;------------------------------------------------
;RDI : Address of the character
; > add64, reg64
;------------------------------------------------
;NOTE : -
;RETN : -
;------------------------------------------------
prtchar:
push rax
push rdi
mov al,byte[rdi]
call prtchr
pop rdi
pop rax
ret
Where did they get "prtchr"? It's not in the man pages.
;--------------------------------
;#16 : prtchr(AL)
;OBJ : Display character in RAX
;--------------------------------
;ARG : The character in RAX(AL)
;--------------------------------
;NOTE : For internal use. Use prtchar
;RETN :
;--------------------------------
prtchr:
push rcx
push r11
push rdi
push rsi
push rdx
push rax
mov edx,1
mov rsi,rsp
mov edi,edx
mov eax,edx
syscall
pop rax
pop rdx
pop rsi
pop rdi
pop r11
pop rcx
ret
Same with a "Pause". Where did they get "getch"?
;------------------------------------------------
;#17 : getch(0)/AL
;OBJ : Get a character from keyboard
;------------------------------------------------
;ARG : -
;------------------------------------------------
;NOTE : Takes single character only
; : For internal use only. Use getchr.
;RETN : The key in AL
;------------------------------------------------
getch:
push rbp
mov rbp,rsp
sub rsp,16
push rdx
push rdi
push rsi
lea rsi,[rbp-2]
mov edx,1
xor edi,edi
xor eax,eax
syscall
xor eax,eax
mov al,byte[rbp-2]
pop rsi
pop rdi
pop rdx
mov rsp,rbp
pop rbp
ret
What does mov rsi,rsp do?Since we're calling sys_write, rsi is the parameter that gives the address of the buffer that we're going to print. Since we pushed rax, and al holds the character we want to print, it tells sys_write that the character's on the stack. Since we started out with rdi pointed to the character,
mov rsi, rdi
might have been more straightforward, but might not have preserved all the registers we want to preserve. Or maybe it just seemed like a good idea at the time.But what do I know.Sounds like you know:
This kind of code is hard to decipherOn that, I think we are all agreed!
6 months down the road.
Thanks, Bryant! I didn't recognize that.
QuoteThis kind of code is hard to decipherOn that, I think we are all agreed!
6 months down the road.
To Bryant,
I downloaded the NASM Tutorial by Ray Toal.
Lot in it . Will take me ages to absorb it.
In converting my 1st windows program these are some
of the things I need to do in NASM:
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.
Right now I can't get past the 1st item.
; 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
global _start
; nasm -f elf32 bluescreen.asm
; ld -o bluescreen bluescreen.o -m elf_i386
section .data
bluescreen db 27, '[30;44m'
bluescreen_len equ $ - bluescreen
yellow db 27, '[30;43m'
yellow_len equ $ - yellow
cls db 27, '[2J'
cls_len equ $ - cls
msg db "hello vt100"
msg_len equ $ - msg
section .text
_start:
mov eax, 4 ; sys_write
mov ebx, 1 ; STDOUT
mov ecx, bluescreen
mov edx, bluescreen_len
int 80h
mov eax, 4 ; sys_write
mov ebx, 1 ; STDOUT
mov ecx, cls
mov edx, cls_len
int 80h
mov eax, 4 ; sys_write
mov ebx, 1 ; STDOUT
mov ecx, yellow
mov edx, yellow_len
int 80h
mov eax, 4 ; sys_write
mov ebx, 1 ; STDOUT
mov ecx, msg
mov edx, msg_len
int 80h
exit:
mov ebx, 0
mov eax, 1
int 80h
Bryant is right, of course. He's showing you how you "should" do it, I'm showing you how you "can" do it.
If you're going to call C libraries, what's the assembly language for? Shouldn't you be programming in C? Assembly language is obsolete, isn't it? Just Joking!
(but seriously, they completely effed up the calling conventions in 64-bit - they are NOT the same!)
Thanks again guys,
Oh my, I'm a glutton for punishment.
I think I have the glibc library. Not sure if I have the
ncurses library. I guess I have to look at the glibc
library through man. When I do man and an item
from the ncurses library nothing happens.
$ sudo apt-get install libncurses5-dev ncurses-doc
Will do my reading and conversion of Bryants program
until I heard about the ncurses library. Didn't think
I would have to get so involved with "C". But whatever
I have to do.....
Windows 10 is an advertising mill by
a software company that has left the programming field!
; 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 elf64 demo64.asm -o demo64.o
; gcc -o demo64 demo64.o -lcurses
;
; Run Process:
; ./demo64
bits 64
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
%define STACK_ALIGN sub rsp, 8
%define STACK_RESTORE add rsp, 8
section .data
hWindow: dq 0
hChildWindow: dq 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:
STACK_ALIGN
;; setup an interrupt to terminate
mov rsi, do_exit
mov rdi, SIGINT
call signal
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp rax, 0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
STACK_RESTORE
mov rax, FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow], rax
;; enable keyboard mapping
mov rsi, TRUE
mov rdi, [hWindow]
call keypad
;; 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 rax, 0
jne .HasColorSupport
;; No color support, return FALSE
STACK_RESTORE
mov rax, FALSE
ret
.HasColorSupport:
call start_color
;; create our color pairs
;; black foreground, blue background
mov rdx, COLOR_BLUE
mov rsi, COLOR_BLACK
mov rdi, BLACK_ON_BLUE
call init_pair
;; black foreground, yellow background
mov rdx, COLOR_YELLOW
mov rsi, COLOR_BLACK
mov rdi, BLACK_ON_YELLOW
call init_pair
;; lets create a child window
mov rcx, 50 ; x value
mov rdx, 10 ; y value
mov rsi, 5 ; 5 columns for 4 digits
mov rdi, 1 ; 1 line for 1 row of digits
call newwin
mov [hChildWindow], rax
;; if we reach this point, we have initialized successfully.
STACK_RESTORE
mov rax, TRUE
ret
;; do_exit : integer -> nothing .
;; exit to the operating system.
do_exit:
STACK_ALIGN
;; refresh our screen
call refresh
;; shut down curses
call endwin
;; return to operating system
mov rdi, 0
call exit
;; we should never reach this point
STACK_RESTORE
ret
;; clear_blue : nothing -> nothing .
;; create a full screen of a light blue color.
clear_blue:
STACK_ALIGN
;; make our background blue
mov rsi, COLOR_PAIR(BLACK_ON_BLUE)
mov rdi, [hWindow]
call wbkgd
;; refresh our screen
mov rdi, [hWindow]
call wrefresh
STACK_RESTORE
ret
;; draw_child_window : nothing -> nothing .
;; put a small rectangle on the screen in yellow.
draw_child_window:
STACK_ALIGN
;; make our background yellow
mov rsi, COLOR_PAIR(BLACK_ON_YELLOW)
mov rdi, [hChildWindow]
call wbkgd
;; refresh our child window
mov rdi, [hChildWindow]
call wrefresh
STACK_RESTORE
ret
;; get_user_input : nothing -> integer .
;; let the user enter 4 digits in black in that rectangle.
get_user_input:
STACK_ALIGN
;; get user input
mov rdx, 4
mov rsi, szUserInput
mov rdi, [hChildWindow]
call wgetnstr
;; convert string to integer
;; rdi, rsi, rdx, rcx, r8, r9
mov rdi, szUserInput
call atoi
STACK_RESTORE
ret
;; main : integer (string . string) -> integer .
;; our program starts here.
main:
STACK_ALIGN
call do_init
cmp rax, 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 ;;
;; RAX register. We can now use it for any- ;;
;; thing we want. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.done:
STACK_RESTORE
xor rdi, rdi
call do_exit
ret
In 64-bit shouldn't all the calls be changed to "syscall"???
Generally I try to avoid the stack like the plague.
Only use it for pushes and pop.
I think I see how you avoid the stack hassle by using
stack align and stack restore.
Why can't I use the registers instead of the stack????
Could I possibly have "glibc" in the wrong place?
I put the demo64 program in home/jack/nasmfld
This is what I get when running gcc -o demo64 demo64.o -lcurses nasmbld:
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 11 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 12 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 13 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 14 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 15 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 16 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 17 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 18 has invalid symbol index 13
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_info): relocation 19 has invalid symbol index 21
/usr/bin/ld: /usr/lib/debug/usr/lib/x86_64-linux-gnu/crt1.o(.debug_line): relocation 0 has invalid symbol index 2
/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/crt1.o:/build/eglibc-3GlaMS/eglibc-2.19/csu/../sysdeps/x86_64/start.S:118: first defined here
collect2: error: ld returned 1 exit status
Got these errors using: ld -o demo64 demo64.o in home/jack/nasmfld:
jack@jack-myheadache ~/nasmfld $ ld -o demo64 demo64.o:
demo64.o: In function `do_init':
demo64.asm:(.text+0x14): undefined reference to `signal'
demo64.asm:(.text+0x19): undefined reference to `initscr'
demo64.o: In function `do_init.CursesInitSuccessful':
demo64.asm:(.text+0x3f): undefined reference to `keypad'
demo64.asm:(.text+0x44): undefined reference to `nonl'
demo64.asm:(.text+0x49): undefined reference to `cbreak'
demo64.asm:(.text+0x4e): undefined reference to `echo'
demo64.asm:(.text+0x53): undefined reference to `has_colors'
demo64.o: In function `do_init.HasColorSupport':
demo64.asm:(.text+0x68): undefined reference to `start_color'
demo64.asm:(.text+0x7c): undefined reference to `init_pair'
demo64.asm:(.text+0x90): undefined reference to `init_pair'
demo64.asm:(.text+0xa9): undefined reference to `newwin'
demo64.o: In function `do_exit':
demo64.asm:(.text+0xc4): undefined reference to `refresh'
demo64.asm:(.text+0xc9): undefined reference to `endwin'
demo64.asm:(.text+0xd0): undefined reference to `exit'
demo64.o: In function `clear_blue':
demo64.asm:(.text+0xef): undefined reference to `wbkgd'
demo64.asm:(.text+0xfc): undefined reference to `wrefresh'
demo64.o: In function `draw_child_window':
demo64.asm:(.text+0x117): undefined reference to `wbkgd'
demo64.asm:(.text+0x124): undefined reference to `wrefresh'
demo64.o: In function `get_user_input':
demo64.asm:(.text+0x149): undefined reference to `wgetnstr'
jack@jack-myheadache ~/nasmfld $
ld -s -o demo /usr/lib/i386-linux-gnu/crti.o /usr/lib/i386-linux-gnu/crt1.o /usr/lib/i386-linux-gnu/crtn.o -I/lib/ld-linux.so.2 demo.o -lc -lcurses
gcc -o demo demo.o -lcurses
Thanks Bryant,
I took out global_start and _start.
Everything worked :)
Got a light blue screen and a light yellow rectangle.
It accepted 4 digits.
Hope it's ok for me to delete my long post like I did the other one.
I'll evidently have more questions as I proceed with the program.
I really don't understand all the things you did or if I should spend
a lot of time trying to figure it out or proceed with the program
and hope with more learning of NASM that things will eventually
fall in place.
The blue screen takes up about 1/4 of the screen and should be
the entire screen.
Would like a lighter blue. The yellow rectangle
needs to be a brighter yellow.
#include <stdio.h>
#include <curses.h>
int main (void)
{
printf ("%%define A_BOLD 0x%X\n", A_BOLD);
return (0);
}[/bold]
Building and running this program gives me the following output:
[code]$ gcc -o bold bold.c
$ ./bold
%define A_BOLD 0x200000
$
How to place the rectangle in a different place on the screen? Want to place a message for
the user in front of the rectangle on the same line.
I am hoping your example will give me enough NASM knowledge
to do the other 199 programs I need to convert.
Another problem I need to worry about. With all these added programs,
and the "C" lib and tutorials, I would never be able to reconstruct
what I have now, if I lost it all due to a meteorite hitting my computer.
Of course I do back up the computer regularly. Maybe I am to paranoid.
One wonders how others trying to write or convert programs in
NASM manage. I certainly couldn't....
In order to save space on the NASM site, if I have to post
a lot of code again, how do you do that scrolling goodie
you use?
This is source code
About ncurses. I would think I need this for any fine tuning
of a monitor screen. If I key in 'man ncurses' in a terminal
am I looking at the complete ncurses?
If not, where can I get the complete list?>
Bryants comment:
"In the directory where you got a clean build, you should have a file named demo64 without any extension. that file should be marked executable. You can run it using the command ./demo64 in the same directory."
Here's what I do: click on demo64 with no extension, right click in an open space and in the window that comes up I click on "Open a Terminal". This gives me a small
screen in a window called terminal. If I left click on demo64, it brings up a window
and an "execution" tab. Clicking on this tab does nothing.
Found this in ncurses:
The ncurses library permits manipulation of data structures, called
windows, which can be thought of as two-dimensional arrays of charac?
ters representing all or part of a CRT screen. A default window called
stdscr, which is the size of the terminal screen, is supplied. Others
may be created with newwin.
I changed your program slightly:
;; lets create a child window
; mov rcx, 50 ; x value
; mov rdx, 10 ; y value
; mov rsi, 5 ; 5 columns for 4 digits
; mov rdi, 1 ; 1 line for 1 row of digits
; call newwin
mov rcx,0 ; x value
mov rdx,0 ; y value
mov rsi,5 ; 5 columns for 4 digits
mov rdi,1 ; 1 line for 1 row of digits
call newwin
This didn't cut the mustard. Still getting a terminal 1/4 sized window.
I'll take it 1 step at a time and try to get the screen to fill the
entire page.
About ncurses. I would think I need this for any fine tuning
of a monitor screen. If I key in 'man ncurses' in a terminal
am I looking at the complete ncurses?
If not, where can I get the complete list?
Here's what I do: click on demo64 with no extension, right click in an open space and in the window that comes up I click on "Open a Terminal". This gives me a small
screen in a window called terminal. If I left click on demo64, it brings up a window
and an "execution" tab. Clicking on this tab does nothing.
Found this in ncurses:
The ncurses library permits manipulation of data structures, called
windows, which can be thought of as two-dimensional arrays of charac?
ters representing all or part of a CRT screen. A default window called
stdscr, which is the size of the terminal screen, is supplied. Others
may be created with newwin.
I changed your program slightly:Code: [Select];; lets create a child window
This didn't cut the mustard. Still getting a terminal 1/4 sized window.
; mov rcx, 50 ; x value
; mov rdx, 10 ; y value
; mov rsi, 5 ; 5 columns for 4 digits
; mov rdi, 1 ; 1 line for 1 row of digits
; call newwin
mov rcx,0 ; x value
mov rdx,0 ; y value
mov rsi,5 ; 5 columns for 4 digits
mov rdi,1 ; 1 line for 1 row of digits
call newwin
I'll take it 1 step at a time and try to get the screen to fill the
entire page.
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp rax, 0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
STACK_RESTORE
mov rax, FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow], rax
On the NASM forum i'm lucky if I get 1 response per day to my questions.
With no books to study about the language and erroneous, outdated and
hard to find solutions, one wonders how anyone can program in NASM.
Hi Bryant,
Haven't read your last post yet but will.
I wanted you to see this stripped down version of your
program that just tries to put a blue screen on the monitor,
not the terminal. It puts a blue screen on the monitor filling
the same size as the terminal (1/4 of the screen)
I downloaded "xterm" and it did the same thing as the regular
terminal in Nasm. My problem is that I can't expect a user to
change to a console mode. I will try your suggestion and read
the 3 sites you gave me. Thanks.
; 2-26-2016 using NASM 64
; Order of colors: BGR
;
; This is a stripped down version of your program.
; Trying to fill the screen of whatever monitor is
; in place in light blue.
; Dependencies:
; libc-dev - GNU C library.
; libncurses-dev - Developer's libraries for ncurses.
; Build Process:
; nasm -f elf64 demo64.asm -o demo64.o
; gcc -o demo64 demo64.o -lcurses
; Run Process:
; ./demo64
bits 64
cpu IA64
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
%define BLACK_ON_BLUE 1
%define BLACK_ON_YELLOW 2
%define STACK_ALIGN sub rsp, 8
%define STACK_RESTORE add rsp, 8
section .data
hWindow: dq 0
hChildWindow: dq 0
szUserInput: db 0, 0, 0, 0, 0
; test code begin
msg db "got past clear_blue "
; test code end
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:
STACK_ALIGN
;; setup an interrupt to terminate
mov rsi,do_exit
mov rdi,SIGINT
call signal
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp rax,0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
mov rax,FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow],rax
;; does this system support color terminals?
call has_colors
cmp rax,0
jne .HasColorSupport
;; No color support, return FALSE
STACK_RESTORE
mov rax,FALSE
ret
.HasColorSupport:
call start_color
;; create our color pairs
;; black foreground, blue background
mov rdx,COLOR_BLUE
mov rsi,COLOR_BLACK
mov rdi,BLACK_ON_BLUE
call init_pair
;; if we reach this point, we have initialized successfully.
STACK_RESTORE
mov rax,TRUE
ret
;; do_exit : integer -> nothing .
;; exit to the operating system.
do_exit:
STACK_ALIGN
;; refresh our screen
call refresh
;; shut down curses
call endwin
;; return to operating system
push qword 0
call exit
add rsp,4
;; we should never reach this point
STACK_RESTORE
ret
;; clear_blue : nothing -> nothing .
;; create a full screen of a light blue color.
clear_blue:
STACK_ALIGN
;; make our background blue
mov rsi,COLOR_PAIR(BLACK_ON_BLUE)
mov rdi,[hWindow]
call wbkgd
;; refresh our screen
mov rdi, [hWindow]
call wrefresh
STACK_RESTORE
ret
;; main : integer (string . string) -> integer .
;; our program starts here.
main:
STACK_ALIGN
call do_init
cmp rax,TRUE
jne .done
;; clear the screen to blue
call clear_blue
; test code begin
mov rax,1 ; sys-write
mov rdi,1 ; standard output
mov rsi,msg
mov rdx,21 ; message length
syscall ; write message to screen
mov rax,60 ; sys_exit
mov rdi,0 ; error code
syscall ; exit
; test code end
.done:
STACK_RESTORE
xor rdi,rdi
call do_exit
ret
Hi Bryant,
Haven't read your last post yet but will.
I wanted you to see this stripped down version of your
program that just tries to put a blue screen on the monitor,
not the terminal
It puts a blue screen on the monitor filling the same size as the
terminal (1/4 of the screen)Code: [Select]; 2-26-2016 using NASM 64
; Order of colors: BGR
;
; This is a stripped down version of your program.
; Trying to fill the screen of whatever monitor is
; in place in light blue.
; Dependencies:
; libc-dev - GNU C library.
; libncurses-dev - Developer's libraries for ncurses.
; Build Process:
; nasm -f elf64 demo64.asm -o demo64.o
; gcc -o demo64 demo64.o -lcurses
; Run Process:
; ./demo64
bits 64
cpu IA64
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
%define BLACK_ON_BLUE 1
%define BLACK_ON_YELLOW 2
%define STACK_ALIGN sub rsp, 8
%define STACK_RESTORE add rsp, 8
section .data
hWindow: dq 0
hChildWindow: dq 0
szUserInput: db 0, 0, 0, 0, 0
; test code begin
msg db "got past clear_blue "
; test code end
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:
STACK_ALIGN
;; setup an interrupt to terminate
mov rsi,do_exit
mov rdi,SIGINT
call signal
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp rax,0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
mov rax,FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow],rax
;; does this system support color terminals?
call has_colors
cmp rax,0
jne .HasColorSupport
;; No color support, return FALSE
STACK_RESTORE
mov rax,FALSE
ret
.HasColorSupport:
call start_color
;; create our color pairs
;; black foreground, blue background
mov rdx,COLOR_BLUE
mov rsi,COLOR_BLACK
mov rdi,BLACK_ON_BLUE
call init_pair
;; if we reach this point, we have initialized successfully.
STACK_RESTORE
mov rax,TRUE
ret
;; do_exit : integer -> nothing .
;; exit to the operating system.
do_exit:
STACK_ALIGN
;; refresh our screen
call refresh
;; shut down curses
call endwin
;; return to operating system
push qword 0
call exit
add rsp,4
;; we should never reach this point
STACK_RESTORE
ret
;; clear_blue : nothing -> nothing .
;; create a full screen of a light blue color.
clear_blue:
STACK_ALIGN
;; make our background blue
mov rsi,COLOR_PAIR(BLACK_ON_BLUE)
mov rdi,[hWindow]
call wbkgd
;; refresh our screen
mov rdi, [hWindow]
call wrefresh
STACK_RESTORE
ret
;; main : integer (string . string) -> integer .
;; our program starts here.
main:
STACK_ALIGN
call do_init
cmp rax,TRUE
jne .done
;; clear the screen to blue
call clear_blue
; test code begin
mov rax,1 ; sys-write
mov rdi,1 ; standard output
mov rsi,msg
mov rdx,21 ; message length
syscall ; write message to screen
mov rax,60 ; sys_exit
mov rdi,0 ; error code
syscall ; exit
; test code end
.done:
STACK_RESTORE
xor rdi,rdi
call do_exit
ret
; test code begin
mov rax,1 ; sys-write
mov rdi,1 ; standard output
mov rsi,msg
mov rdx,21 ; message length
syscall ; write message to screen
; test code begin
msg db "got past clear_blue "
; test code end
; test code begin
msg db "got past clear_blue ", 0
; test code end
; test code begin
mov rsi, msg
mov rdi, [hWindow]
call waddstr
mov rax,60 ; sys_exit
mov rdi,0 ; error code
syscall ; exit
; test code end
;; return to operating system
push qword 0
call exit
add rsp,4
;; return to operating system
mov rdi, 0
call exit
Hi Bryant,
I made the changes you last posted.
I have no idea if this library is on my computer.
; libncurses-dev - Developer's libraries for ncurses.
Maybe hwindow is not getting loaded
your code:Code: [Select];; was curses initialization successful?
my comment: at this point I would think that rax has a "1" in it.
cmp rax,0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
mov rax,FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow],rax
Is that correct???
I have this message after hwindow is loaded.Code: [Select]; test code begin.
I can not test after initscr because I don't know how to
; msg2 db "hwindow is loaded ",0
mov rdi,[hWindow]
mov rsi,msg2
call waddstr ; write message to screen
; test code end
change the test code from hwindow to a test of rax. It is
not loaded at the initscr call yet.
; 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 elf64 demo64.asm -o demo64.o
; gcc -o demo64 demo64.o -lcurses
;
; Run Process:
; ./demo64
bits 64
global main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions from the Standard C Library
extern signal
extern fputs ;; we'll need this for an error message without curses.
extern exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions from the NCurses Library
extern initscr
extern nodelay
extern noecho
extern nonl
extern cbreak
extern keypad
extern has_colors
extern start_color
extern init_pair
extern endwin
extern refresh
extern wrefresh
extern wattron
extern waddstr
extern wgetch
%define STDIN 0
%define STDOUT 1
%define STDERR 2
%define SIGINT 2 ; defined in signal.h
%define TRUE 1 ; defined in curses.h
%define FALSE 0 ; defined in curses.h
%define ERR (-1) ; defined in curses.h
%define COLOR_BLACK 0
%define COLOR_YELLOW 3
%define COLOR_PAIR(n) ((n) << (8))
%define BLACK_ON_YELLOW 1
%define STACK_ALIGN sub rsp, 8
%define STACK_RESTORE add rsp, 8
section .rodata
szNCursesHelloWorld: db "Hello, ncurses world!", 0
szNCursesInitFailed: db "ncurses initialization; failed.", 0
section .data
hWindow: dq 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:
STACK_ALIGN
;; setup an interrupt to terminate
mov rsi, do_exit
mov rdi, SIGINT
call signal
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp rax, 0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
STACK_RESTORE
mov rax, FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow], rax
;; enable keyboard mapping
mov rsi, TRUE
mov rdi, [hWindow]
call keypad
;; 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
;; Don't wait on input from wgetch, we'll just poll on user input instead.
call nodelay
;; disable character echoing
call noecho
;; does this system support color terminals?
call has_colors
cmp rax, 0
jne .HasColorSupport
;; No color support, return FALSE
STACK_RESTORE
mov rax, FALSE
ret
.HasColorSupport:
call start_color
;; create our color pairs
;; black foreground, yellow background
mov rdx, COLOR_YELLOW
mov rsi, COLOR_BLACK
mov rdi, BLACK_ON_YELLOW
call init_pair
;; if we reach this point, we have initialized successfully.
STACK_RESTORE
mov rax, TRUE
ret
;; do_exit : integer -> nothing .
;; exit to the operating system.
do_exit:
STACK_ALIGN
;; refresh our screen
call refresh
;; shut down curses
call endwin
;; return to operating system
mov rdi, 0
call exit
;; we should never reach this point
STACK_RESTORE
ret
;; main : integer (string . string) -> integer .
;; our program starts here.
main:
STACK_ALIGN
call do_init
cmp rax, FALSE
jne .initSuccess
;; do_init failed so let's display a message to the console
;; instead of the ncurses window (since it doesn't exist).
mov esi, szNCursesInitFailed
mov edi, STDERR
call fputs
jmp .done
.initSuccess:
;; At this point, ncurses's has successfully initialized and
;; hWindow contains a pointer to the stdscr structure.
;; Display our message in black text on a yellow background.
mov esi, COLOR_PAIR(BLACK_ON_YELLOW)
mov edi, [hWindow]
call wattron
mov esi, szNCursesHelloWorld
mov edi, [hWindow]
call waddstr
;; The last two commands wrote a string on the window buffer,
;; now we need to display that buffer on the screen.
mov edi, [hWindow]
call wrefresh
;; Now that we've displayed something on the screen, we should
;; wait for the user to hit any key. We set the user input to
;; nonblocking mode with (nodelay) earlier, so wgetch returns
;; a translated keycode from the user input, if the user hasn't
;; hit a key, it will immediately return ERR. We loop on this
;; until we get input from the user.
.getChar:
mov edi, [hWindow]
call wgetch
cmp eax, ERR
jne .getChar
;; once the user has it a key, we can now exit the application.
;; we only waited on user input so the message we displayed can
;; be read by the user.
.done:
STACK_RESTORE
xor rdi, rdi
call do_exit
ret
Please a little clarification:
I see so much on the internet of programmers using 80h, syscall and no ncurses.
Is ncurses something new or just better than the old way?
Thank you Bryant for your patience.
About "initscr".
If I understand correctly: initscr puts a zero in rax
if initscr fails and puts a pointer in rax if initscr is good.
I tried to run your new program and I got a segmentation fault.
section .rodata - is just a typo or does it make any difference?
Will continue looking to see if I can find what's causing it.
; Dependencies:
; libc-dev - GNU C library.
; libncurses-dev - Developer's libraries for ncurses.
; Build Process:
; nasm -f elf64 hello64.asm -o hello64.o
; gcc -o hello64 hello64.o -lcurses
;
; Run Process:
; ./hello64
bits 64
global main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions from the Standard C Library
extern signal
extern fputs ;; we'll need this for an error message without curses.
extern exit
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Functions from the NCurses Library
extern initscr
extern noecho
extern nonl
extern cbreak
extern keypad
extern has_colors
extern start_color
extern init_pair
extern endwin
extern refresh
extern wrefresh
extern wattron
extern waddstr
extern wgetch
%define STDIN 0
%define STDOUT 1
%define STDERR 2
%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_YELLOW 3
%define COLOR_PAIR(n) ((n) << (8))
%define BLACK_ON_YELLOW 1
%define STACK_ALIGN sub rsp, 8
%define STACK_RESTORE add rsp, 8
section .rodata
szNCursesHelloWorld: db "Hello, ncurses world!", 0
szNCursesInitFailed: db "ncurses initialization; failed.", 0
section .data
hWindow: dq 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:
STACK_ALIGN
;; setup an interrupt to terminate
mov rsi, do_exit
mov rdi SIGINT
call signal
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp rax, 0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
STACK_RESTORE
mov rax, FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow], rax
;; enable keyboard mapping
mov rsi, TRUE
mov rdi, [hWindow]
call keypad
;; 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
;; disable character echoing
call noecho
;; does this system support color terminals?
call has_colors
cmp rax, 0
jne .HasColorSupport
;; No color support, return FALSE
STACK_RESTORE
mov rax, FALSE
ret
.HasColorSupport:
call start_color
;; create our color pairs
;; black foreground, yellow background
mov rdx, COLOR_YELLOW
mov rsi, COLOR_BLACK
mov rdi, BLACK_ON_YELLOW
call init_pair
;; if we reach this point, we have initialized successfully.
STACK_RESTORE
mov rax, TRUE
ret
;; do_exit : integer -> nothing .
;; exit to the operating system.
do_exit:
STACK_ALIGN
;; refresh our screen
call refresh
;; shut down curses
call endwin
;; return to operating system
mov rdi, 0
call exit
;; we should never reach this point
STACK_RESTORE
ret
;; main : integer (string . string) -> integer .
;; our program starts here.
main:
STACK_ALIGN
call do_init
cmp rax, FALSE
jne .initSuccess
;; do_init failed so let's display a message to the console
;; instead of the ncurses window (since it doesn't exist).
mov rsi, szNCursesInitFailed
mov rdi, STDERR
call fputs
jmp .done
.initSuccess:
;; At this point, ncurses's has successfully initialized and
;; hWindow contains a pointer to the stdscr structure.
;; Display our message in black text on a yellow background.
mov rsi, COLOR_PAIR(BLACK_ON_YELLOW)
mov rdi, [hWindow]
call wattron
mov rsi, szNCursesHelloWorld
mov rdi, [hWindow]
call waddstr
;; The last two commands wrote a string on the window buffer,
;; now we need to display that buffer on the screen.
mov rdi, [hWindow]
call wrefresh
;; Now that we've displayed something on the screen, we should
;; wait for the user to hit any key.
mov rdi, [hWindow]
call wgetch
;; once the user has it a key, we can now exit the application.
;; we only waited on user input so the message we displayed can
;; be read by the user.
.done:
STACK_RESTORE
mov rdi, 0
call do_exit
ret
I am having no luck with "alt+ctrl+f1-f8". Where would I execute it?
Running Linux mint 17.3 rosa xfce
Thanks Bryant,
That worked. Got a black screen, with a yellow rectangle,
the message and a terminal sized screen.
Left out a comma. Fixed it and everything ran fine.
In Windows I frequently used Ctrl+Alt+Delete.
I go into /home/jack/nasmfld. Then I click on demo64.exe.
Go to a clear space and RC and click on open in terminal.
Then I do alt+ctrl+f8. I get a screen with the cursor setting
at Jack@jack-myheadache. I would think at this point I
need to change back into /home/jack/nasmfld to execute
demo64. I don't know how to do that.
Thanks again Bryant.
Cut my baby teeth on DOS. It's an old friend.
However, need to do that reading on Linux.
To get the wide screen I clicked on the xfce terminal icon.
Did cd /home/jack/nasmfld. Hit enter.
Keyed in ./demo64 and voila, got a full screen. :)
Only question I have about all this is, it will not work
for a user. They want to run an ex: "demo64.exe" and be
in the full screen without doing anything else....
#!/bin/sh
x-terminal-emulator -e ./demo64
[Desktop Entry]
Type=Application
Terminal=true
Name=Demo64
Comment=A simple 64-bit NASM demo.
Icon=
Exec=./demo64
Path=
HI Bryant,
1. The following pretty much lost me.
EX: I read the "man chmod" and didn't understand it.
So I am not able to fill this out "chmod +x demo64.sh".
2. The next example. Am I supposed to fill out those fields or just
use it as is???
Which one should I use?
3.
I need to make sure that the user only enters
digits in demo64. I read the man pages on these two calls
and again I didn't understand the explanation. How do you
know what to put where? Have no idea how to enter the x/y
coordinates for placing a message.
;------------------------------------------------
; 3-1-2016 using NASM 64
; Order of colors: BGR
;
; Bryants goodies
; 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 elf64 demo64.asm -o demo64.o
; gcc -o demo64 demo64.o -lcurses
; Run Process:
; ./demo64
bits 64
cpu IA64
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 waddstr
extern wattron
extern wrefresh
extern wgetch
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 STDERR 2
%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
%define BLACK_ON_BLUE 1
%define BLACK_ON_YELLOW 2
%define STACK_ALIGN sub rsp, 8
%define STACK_RESTORE add rsp, 8
section .data
hWindow: dq 0
hChildWindow: dq 0
szUserInput: db 0, 0, 0, 0, 0
uinputerr db "only digits may be entered - enter again",0
section .text
; global _start ;?? bryant said these are included in the "c" lib
;_start: ;??
;; 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:
STACK_ALIGN
;; setup an interrupt to terminate
mov rsi,do_exit
mov rdi,SIGINT
call signal
;; initialize the curses library
call initscr
;; was curses initialization successful?
cmp rax,0
jne .CursesInitSuccessful
;; initialization failed, return FALSE
mov rax,FALSE
ret
.CursesInitSuccessful:
;; save a copy of curses root window
mov [hWindow],rax
;; enable keyboard mapping
mov rsi,TRUE
mov rdi,[hWindow]
call keypad
;; 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 rax,0
jne .HasColorSupport
;; No color support, return FALSE
STACK_RESTORE
mov rax,FALSE
ret
.HasColorSupport:
call start_color
;; create our color pairs
;; black foreground, blue background
mov rdx,COLOR_BLUE
mov rsi,COLOR_BLACK
mov rdi,BLACK_ON_BLUE
call init_pair
;; black foreground, yellow background
mov rdx,COLOR_YELLOW
mov rsi,COLOR_BLACK
mov rdi,BLACK_ON_YELLOW
call init_pair
;; lets create a child window
mov rcx,50 ; x value
mov rdx,10 ; y value
mov rsi,5 ; 5 columns for 4 digits
mov rdi,1 ; 1 line for 1 row of digits
call newwin
mov [hChildWindow],rax
;; if we reach this point, we have initialized successfully.
STACK_RESTORE
mov rax,TRUE
ret
;; do_exit : integer -> nothing .
;; exit to the operating system.
do_exit:
STACK_ALIGN
;; refresh our screen
call refresh
;; shut down curses
call endwin
;; return to operating system
mov rdi,0
call exit
;; we should never reach this point
STACK_RESTORE
ret
;; clear_blue : nothing -> nothing .
;; create a full screen of a light blue color.
clear_blue:
STACK_ALIGN
;; make our background blue
mov rsi,COLOR_PAIR(BLACK_ON_BLUE)
mov rdi,[hWindow]
call wbkgd
;; refresh our screen
mov rdi, [hWindow]
call wrefresh
STACK_RESTORE
ret
;; draw_child_window : nothing -> nothing .
;; put a small rectangle on the screen in yellow.
draw_child_window:
STACK_ALIGN
;; make our background yellow
mov rsi,COLOR_PAIR(BLACK_ON_YELLOW)
mov rdi,[hChildWindow]
call wbkgd
;; refresh our child window
mov rdi,[hChildWindow]
call wrefresh
STACK_RESTORE
ret
;; get_user_input : nothing -> integer.
;; let the user enter 4 digits in black in the rectangle.
get_user_input:
STACK_ALIGN
;; get user input
;; here I am trying to test the input from the user for valid
;; digits. The error message should go on the same line as the
;; yellow rectangle. This bad code gives the error message at
;; x-0,y-0. The yellow rectangle is not cleared for new input.
.n1:
mov rdx,4
mov rsi,szUserInput
mov rdi,[hChildWindow]
call wgetnstr ; reads all 4 characters good or bad
mov rsi,szUserInput ; check user input for digits
mov ah,3
.n2:
cmp ah,3 ; process 4 digits
jg .out1 ; good input
mov al,[rsi]
cmp al,0
jl .err1
cmp al,9
jg .err1
inc ah
inc rsi
jmp .n2
.err1:
;; Display error message in black text on a yellow background.
mov rsi,COLOR_PAIR(BLACK_ON_YELLOW)
mov rcx,5 ;???? x value
mov rdx,10 ;????? y value
mov rdi, [hWindow]
call wattron
;uinputerr db "only digits may be entered - start over",0
mov rsi,uinputerr
mov rdi, [hWindow]
call waddstr
;; The last two commands wrote a string on the window buffer,
;; now we need to display that buffer on the screen.
mov rdi, [hWindow]
call wrefresh
call draw_child_window
jmp .n1
.out1:
;; convert string to integer
;; rdi, rsi, rdx, rcx, r8, r9
mov rdi,szUserInput
call atoi
STACK_RESTORE
ret
;; main : integer (string . string) -> integer .
;; our program starts here.
main:
STACK_ALIGN
call do_init
cmp rax,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 ;;
;; RAX register. We can now use it for any- ;;
;; thing we want. ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.done:
STACK_RESTORE
xor rdi,rdi
call do_exit
ret
HI Bryant,
1. The following pretty much lost me.
EX: I read the "man chmod" and didn't understand it.
So I am not able to fill this out "chmod +x demo64.sh".
2. The next example. Am I supposed to fill out those fields or just
use it as is???
Which one should I use?
3.
I need to make sure that the user only enters
digits in demo64. I read the man pages on these two calls
and again I didn't understand the explanation.
How do you
know what to put where?
Have no idea how to enter the x/y
coordinates for placing a message.
mov rdx, [x_val]
mov rsi, [y_val]
mov rdi, [hWindow]
call wmove
I'm still having problems with your last post. I will put that aside
for now and continue trying to complete my 1st program.
I have read the man page about "getmaxyx" and don't understand
the format of the instruction.
void getmaxyx(WINDOW *win, int y, int x)
What I need is to get the number of columns on a monitor.
extern LINES
extern COLS
;; get_max_coord : window_handle -> { x y }
;; Obtains the max X and Y coordinates from a window handle
;; and returns the maximum X coordinate in rax and the maximum
;; Y coordinate in rbx.
%macro get_max_coord 1
push rsi
mov rsi, %1
xor rax, rax
xor rbx, rbx
mov ax, [rsi + 6]
mov bx, [rsi + 4]
pop rsi
%endmacro
;; get_cur_coord : window_handle -> { x y }
;; Obtains the current X and Y coordinates from a window handle
;; and returns the current X coordinate in rax and the current
;; Y coordinate in rbx.
%macro get_cur_coord 1
push rsi
mov rsi, %1
xor rax, rax
xor rbx, rbx
mov ax, [rsi + 2]
mov bx, [rsi]
pop rsi
%endmacro
Optional, after a label defining a variable. If the label is the only thing on the line. Nasm will generate a suppressible warning.
hWindow: dq 0
hChildWindow: dq 0
szUserInput: db 0, 0, 0, 0, 0
Why the colon after items in the Data section????
If the user enters this data '1234'31h, 32h, 33h, 34h
is it coded as 31,32,33,34
All the input fields must be digits.You'll have to check those "by hand".
1st two can not be greater than 22.
2nd two can not be greater than 08.
xor rsi,rsi
.t1:
mov ch,byte [szUserInput+rsi]
inc rsi
jmp .t1
that's fine, or as you had it before the edit:$define B byte
xor rsi,rsi
.t1:
mov ch,B[szUserInput+rsi]
inc rsi
jmp .t1
Since the register cl determines the size of the operation, we don't really need to say "byte" at all. May make it clearer for us humans, but Nasm knows. :)I like to keep my program files separate from any OS.
OSes: Linux mint 17.3 rosa excp 64-bit and windows 7 pro 64-bit.
These OSes are on a separate SSD drive.
I do this on a 1T HD. EX: masm32, GoAsm and now NASM.
If the unexpected happens my program files are safe.
I also back up these files regularly.
I can execute the masm32 and GoAsm program from the HD
with no problems...
Today I tried to do the same thing with my demo64 NASM program.
This is what happened: "bash ./demo64: permission denied".
Thanks for any help...
Thanks for responding Bryant,
This is what I got.....
jack@jack-myheadache ~ $ sudo mount -o remount,exec /media/jack
[sudo] password for jack:
mount: can't find /media/jack in /etc/fstab or /etc/mtab
jack@jack-myheadache ~ $
;***************************************************************
Generally I want the whole screen to be Blue and it is.
All heading messages are in White and it is.
I want any error messages to be in say Yellow.
So the problem is how to make just the error messages Yellow
and leave the headings etc. in White? I tried adding an init_pair
Yellow/Blue and all the screen messages became Yellow.
I tried adding the init_pair where I wrote the error message
and it still made everything yellow.
Hope this makes sense....
Generally I want the whole screen to be Blue and it is.
All heading messages are in White and it is.
I want any error messages to be in say Yellow.
So the problem is how to make just the error messages Yellow
and leave the headings etc. in White? I tried adding an init_pair
Yellow/Blue and all the screen messages became Yellow.
I tried adding the init_pair where I wrote the error message
and it still made everything yellow.
Hope this makes sense....
mov r8, 0 ; curses requires the "opts" parameter for future features that aren't currently implemented. so we just set it to 0.
mov rcx, YELLOW_ON_BLUE ; or whatever you named the color pair index using init_color
mov rdx, 0 ; the string attribute; 0 for normal, and 200000h for bold
mov rsi, szMessage_len ; the length of the error message you printed.
mov rdi, [hWindow] ; the window your string was printed on.
call wchgat
3-17-2016
Hi Bryant,
This is what I got from my code below:
#1...........
jack@jack-myheadache ~/nasmfld $ nasm -f elf64 demo64.asm -o demo64.o
jack@jack-myheadache ~/nasmfld $ gcc -o demo64 demo64.o -lcurses
demo64.o: In function `get_user_input.err1':
demo64.asm:(.text+0x4b8): undefined reference to `get_cur_coord'
collect2: error: ld returned 1 exit status
jack@jack-myheadache ~/nasmfld $
extern get_cur_coord ; have no idea how or where to define this
extern wchgat
%define BLACK_ON_YELLOW 2
call get_cur_coord
mov r8, 0 ; curses requires the "opts" parameter for future features
; that aren't currently implemented. so we just set it to 0.
mov rcx, BLACK_ON_YELLOW ; or whatever you named the color pair index using
; init_color
mov rdx, 0 ; the string attribute; 0 for normal, and 200000h for bold
mov rsi,42 ; the length of the error message you printed.
mov rdi, [hWindow] ; the window your string was printed on.
call wchgat
; call draw_child_window3
mov rdx,50 ; X
mov rsi,11 ; Y
; mov rdi,[hChildWindow3]
mov rdi,[hWindow]
call wmove
;*****************
#2................
also never got this to work.
trying to run NASM from a HD not containing the OS.
jack@jack-myheadache ~ $ sudo mount -o remount,exec /media/jack/nasm/nasmfld
[sudo] password for jack:
mount: can't find /media/jack/nasm/nasmfld in /etc/fstab or /etc/mtab
jack@jack-myheadache ~ $
; *****************
#3...................
In MASM32 we have macro called "ATODW".
It converts a decimal string into a dw value.
CkBal db ' 4321',0
mathhold dd 0
I thought this was what "atoi" did....
more about this problem below.
; the user keys in "aa" incorrectly
hChildWindow dq 0
msg dw 0 ; converted user input ??
szUserInput db ' ',0
mov rdx,2
mov rsi,szUserInput
mov rdi,[hChildWindow]
call wgetnstr ; reads 2 characters good or bad
;; convert string to integer
mov rdi,szUserInput
call atoi ; result in rax
mov [msg],ax ; preserve keyed in value ??
cmp byte[msg+1],016h ; This does not work!!!!!!!!!
; value should not be > 22 decimal
jg .err1
jmp .out1 ; good input
; never gets here.............
.err1:
call draw_child_window3
mov rdx,50 ; X
mov rsi,11 ; Y
mov rdi,[hChildWindow3]
call wmove
;msg6 db 'value keyed in is invalid - reenter ',0
mov rsi,msg6
mov rdi,[hChildWindow3]
call waddstr
;; The command wrote a string in the window buffer,
;; now we need to display the buffer on the screen.
mov rdi,[hChildWindow3]
call wrefresh
3-17-2016
Hi Bryant,
This is what I got from my code below:Code: [Select]jack@jack-myheadache ~/nasmfld $ nasm -f elf64 demo64.asm -o demo64.o
jack@jack-myheadache ~/nasmfld $ gcc -o demo64 demo64.o -lcurses
demo64.o: In function `get_user_input.err1':
demo64.asm:(.text+0x4b8): undefined reference to `get_cur_coord'
collect2: error: ld returned 1 exit status
jack@jack-myheadache ~/nasmfld $
Code: [Select]extern get_cur_coord ; have no idea how or where to define this
extern wchgat
%define BLACK_ON_YELLOW 2
call get_cur_coord
mov r8, 0 ; curses requires the "opts" parameter for future features
; that aren't currently implemented. so we just set it to 0.
mov rcx, BLACK_ON_YELLOW ; or whatever you named the color pair index using
; init_color
mov rdx, 0 ; the string attribute; 0 for normal, and 200000h for bold
mov rsi,42 ; the length of the error message you printed.
mov rdi, [hWindow] ; the window your string was printed on.
call wchgat
; call draw_child_window3
mov rdx,50 ; X
mov rsi,11 ; Y
; mov rdi,[hChildWindow3]
mov rdi,[hWindow]
call wmove
;*****************
also never got this to work.
trying to run NASM from a HD not containing the OS.Code: [Select]jack@jack-myheadache ~ $ sudo mount -o remount,exec /media/jack/nasm/nasmfld
[sudo] password for jack:
mount: can't find /media/jack/nasm/nasmfld in /etc/fstab or /etc/mtab
jack@jack-myheadache ~ $
In MASM32 we have macro called "ATODW".
It converts a decimal string into a dw value.
CkBal db ' 4321',0
mathhold dd 0
I thought this was what "atoi" did....
more about this problem below.Code: [Select]; the user keys in "aa" incorrectly
hChildWindow dq 0
msg dw 0 ; converted user input ??
szUserInput db ' ',0
mov rdx,2
mov rsi,szUserInput
mov rdi,[hChildWindow]
call wgetnstr ; reads 2 characters good or bad
;; convert string to integer
mov rdi,szUserInput
call atoi ; result in rax
mov [msg],ax ; preserve keyed in value ??
cmp byte[msg+1],016h ; This does not work!!!!!!!!!
; value should not be > 22 decimal
jg .err1
jmp .out1 ; good input
; never gets here.............
.err1:
call draw_child_window3
mov rdx,50 ; X
mov rsi,11 ; Y
mov rdi,[hChildWindow3]
call wmove
;msg6 db 'value keyed in is invalid - reenter ',0
mov rsi,msg6
mov rdi,[hChildWindow3]
call waddstr
;; The command wrote a string in the window buffer,
;; now we need to display the buffer on the screen.
mov rdi,[hChildWindow3]
call wrefresh
mov al, byte [szUserInput]
cmp al, '0'
jb .err1
cmp al, '9'
ja .err1
mov al, byte [szUserInput+1]
cmp al, '0'
jb .err1
cmp al, '9'
ja .err1
jmp .out1
.err1:
;; one of the characters wasn't a decimal digit,
;; do our error for invalid input then jump to end
;; of procedure.
.out1:
;; both characters read are decimal digits, convert
;; them to integers.
mov rdi, szUserInput
call atoi
Char Dec Oct Hex | Char Dec Oct Hex | Char Dec Oct Hex | Char Dec Oct Hex
-------------------------------------------------------------------------------------
(nul) 0 0000 0x00 | (sp) 32 0040 0x20 | @ 64 0100 0x40 | ` 96 0140 0x60
(soh) 1 0001 0x01 | ! 33 0041 0x21 | A 65 0101 0x41 | a 97 0141 0x61
(stx) 2 0002 0x02 | " 34 0042 0x22 | B 66 0102 0x42 | b 98 0142 0x62
(etx) 3 0003 0x03 | # 35 0043 0x23 | C 67 0103 0x43 | c 99 0143 0x63
(eot) 4 0004 0x04 | $ 36 0044 0x24 | D 68 0104 0x44 | d 100 0144 0x64
(enq) 5 0005 0x05 | % 37 0045 0x25 | E 69 0105 0x45 | e 101 0145 0x65
(ack) 6 0006 0x06 | & 38 0046 0x26 | F 70 0106 0x46 | f 102 0146 0x66
(bel) 7 0007 0x07 | ' 39 0047 0x27 | G 71 0107 0x47 | g 103 0147 0x67
(bs) 8 0010 0x08 | ( 40 0050 0x28 | H 72 0110 0x48 | h 104 0150 0x68
(ht) 9 0011 0x09 | ) 41 0051 0x29 | I 73 0111 0x49 | i 105 0151 0x69
(nl) 10 0012 0x0a | * 42 0052 0x2a | J 74 0112 0x4a | j 106 0152 0x6a
(vt) 11 0013 0x0b | + 43 0053 0x2b | K 75 0113 0x4b | k 107 0153 0x6b
(np) 12 0014 0x0c | , 44 0054 0x2c | L 76 0114 0x4c | l 108 0154 0x6c
(cr) 13 0015 0x0d | - 45 0055 0x2d | M 77 0115 0x4d | m 109 0155 0x6d
(so) 14 0016 0x0e | . 46 0056 0x2e | N 78 0116 0x4e | n 110 0156 0x6e
(si) 15 0017 0x0f | / 47 0057 0x2f | O 79 0117 0x4f | o 111 0157 0x6f
(dle) 16 0020 0x10 | 0 48 0060 0x30 | P 80 0120 0x50 | p 112 0160 0x70
(dc1) 17 0021 0x11 | 1 49 0061 0x31 | Q 81 0121 0x51 | q 113 0161 0x71
(dc2) 18 0022 0x12 | 2 50 0062 0x32 | R 82 0122 0x52 | r 114 0162 0x72
(dc3) 19 0023 0x13 | 3 51 0063 0x33 | S 83 0123 0x53 | s 115 0163 0x73
(dc4) 20 0024 0x14 | 4 52 0064 0x34 | T 84 0124 0x54 | t 116 0164 0x74
(nak) 21 0025 0x15 | 5 53 0065 0x35 | U 85 0125 0x55 | u 117 0165 0x75
(syn) 22 0026 0x16 | 6 54 0066 0x36 | V 86 0126 0x56 | v 118 0166 0x76
(etb) 23 0027 0x17 | 7 55 0067 0x37 | W 87 0127 0x57 | w 119 0167 0x77
(can) 24 0030 0x18 | 8 56 0070 0x38 | X 88 0130 0x58 | x 120 0170 0x78
(em) 25 0031 0x19 | 9 57 0071 0x39 | Y 89 0131 0x59 | y 121 0171 0x79
(sub) 26 0032 0x1a | : 58 0072 0x3a | Z 90 0132 0x5a | z 122 0172 0x7a
(esc) 27 0033 0x1b | ; 59 0073 0x3b | [ 91 0133 0x5b | { 123 0173 0x7b
(fs) 28 0034 0x1c | < 60 0074 0x3c | \ 92 0134 0x5c | | 124 0174 0x7c
(gs) 29 0035 0x1d | = 61 0075 0x3d | ] 93 0135 0x5d | } 125 0175 0x7d
(rs) 30 0036 0x1e | > 62 0076 0x3e | ^ 94 0136 0x5e | ~ 126 0176 0x7e
(us) 31 0037 0x1f | ? 63 0077 0x3f | _ 95 0137 0x5f | (del) 127 0177 0x7f
Hi Bryant,
1. Got it to work using your stuff. I think.
Now if Linux Mint gets corrupted I'll be able to reinstall it
without losing the goodies in NASM.
I compiled the demo64 program on the HD separate from Linux.
That worked fine. When I tried to execute the program I got
the following:
jack@jack-myheadache /media/jack/NASM/nasmfld $ ./demo64
bash: ./demo64: Permission denied
jack@jack-myheadache /media/jack/NASM/nasmfld $
Is it possible that I was not in administrator mode??
Don't know how to get there in Linux.....
2. Trying to understand your explanation of adding colors to the screen.
When I do man wchgat all I get is a screen showing data for "attr"?
3. In Masm32 I avoided Macros like the plague. I like to see, in my code,
the full code for anything that needs repeated. I would write it once
and branch to and return from it as many times as needed. This way I
don't have to go digging for what the macro does and it's parameters.
In NASM I have trouble knowing what is a marco and what are it's
parameters and where to find data on the macro.
This is my problem right now with "get_cur_coord".
Thanks for your help.
Hi Bryant,
1. Got it to work using your stuff. I think.
Now if Linux Mint gets corrupted I'll be able to reinstall it
without losing the goodies in NASM.
I compiled the demo64 program on the HD separate from Linux.
That worked fine. When I tried to execute the program I got
the following:
jack@jack-myheadache /media/jack/NASM/nasmfld $ ./demo64
bash: ./demo64: Permission denied
jack@jack-myheadache /media/jack/NASM/nasmfld $
Is it possible that I was not in administrator mode??
Don't know how to get there in Linux.....
$ sudo chown -R jack /media/jack
2. Trying to understand your explanation of adding colors to the screen.
When I do man wchgat all I get is a screen showing data for "attr"?
int wchgat(WINDOW *win, int n, attr_t attr,
short color, const void *opts)
The routine chgat changes the attributes of a given number of charac?
ters starting at the current cursor location of stdscr. It does not
update the cursor and does not perform wrapping. A character count of
-1 or greater than the remaining window width means to change at?
tributes all the way to the end of the current line. The wchgat func?
tion generalizes this to any window;the mvwchgat function does a cur?
sor move before acting. In these functions, the color argument is a
color-pair index (as in the first argument of init_pair, see col?
or(3NCURSES)). The opts argument is not presently used, but is re?
served for the future (leave it NULL).
3. In Masm32 I avoided Macros like the plague. I like to see, in my code,
the full code for anything that needs repeated. I would write it once
and branch to and return from it as many times as needed. This way I
don't have to go digging for what the macro does and it's parameters.
In NASM I have trouble knowing what is a marco and what are it's
parameters and where to find data on the macro.
This is my problem right now with "get_cur_coord".
Thanks for your help.
;; process_name : inputs -> outputs
;; get_cur_coord : window_handle -> { x y }
;; Obtains the current X and Y coordinates from a window handle
;; and returns the current X coordinate in rax and the current
;; Y coordinate in rbx.
get_cur_coord [hWindow]
;; given
;; wmove (hWindow, 0, 0); get_cur_coord [hWindow] => { RAX: 0, RBX 0 },
;; wmove (hWindow, 5, 4); get_cur_coord [hwindow] => { RAX: 4, RBX 5 }, and
;; wmove (hWindow, LINES, COLS); get_curr_coord [hWindow] => { RAX: COLS, RBX: LINES }.
get_cur_coord_ut:
STACK_ALIGN
;; given wmove (hWindow, 0, 0); get_cur_coord [hWindow]
mov rdx, 0
mov rsi, 0
mov rdi, [hWindow]
call wmove
get_cur_coord [hWindow]
;; expect { RAX: 0, RBX 0 }
cmp rax, 0
jne .FAIL
cmp rbx, 0
jne .FAIL
;; given wmove (hWindow, 5, 4); get_cur_coord [hwindow]
mov rdx, 4
mov rsi, 5
mov rdi, [hWindow]
call wmove
get_cur_coord [hWindow]
;; expect { RAX: 4, RBX 5 }
cmp rax, 4
jne .FAIL
cmp rbx, 5
jne .FAIL
;; given wmove (hWindow, LINES, COLS); get_curr_coord [hWindow]
mov rdx, [COLS]
mov rsi, [LINES]
mov rdi, [hWindow]
call wmove
get_cur_coord [hWindow]
;; expect { RAX: COLS, RBX: LINES }
cmp rax, [COLS]
jne .FAIL
cmp rbx, [LINES]
jne .FAIL
.SUCCESS:
mov rax, TRUE
jmp .DONE
.FAIL:
mov rax, FALSE
.DONE:
STACK_RESTORE
ret
%macro get_cur_coord 1
push rsi
mov rsi, %1
xor rax, rax
xor rbx, rbx
mov ax, [rsi + 2]
mov bx, [rsi]
pop rsi
%endmacro
;; get_cur_coord_proc : window_handle -> { x y }.
;; Obtains the current coordinates from a window handle in RDI
;; and returns the current x-coordinate in RAX and the current
;; y-coordinate in RBX.
;; given
;; wmove (hWindow, 0, 0); get_cur_coord_proc (hWindow) => { RAX: 0, RBX 0 },
;; wmove (hWindow, 5, 4); get_cur_coord_proc (hwindow) => { RAX: 4, RBX 5 }, and
;; wmove (hWindow, LINES, COLS); get_curr_coord_proc (hWindow) => { RAX: COLS, RBX: LINES }.
get_cur_coord_proc:
STACK_ALIGN
xor rax, rax
xor rbx, rbx
mov ax, [rdi + 2] ; second element (x-coord)
mov bx, [rdi] ; first element (y-coord)
STACK_RESTORE
ret
Hi Bryant,
1. Still trying to get nasm to work on the separate HD.
jack@jack-myheadache /media/jack/NASM/nasmfld $ sudo chown -R jack /media/jack
[sudo] password for jack:
jack@jack-myheadache /media/jack/NASM/nasmfld $ nasm -f elf64 demo64.asm -o demo64.o
jack@jack-myheadache /media/jack/NASM/nasmfld $ gcc -o demo64 demo64.o -lcurses
jack@jack-myheadache /media/jack/NASM/nasmfld $ ./demo64
bash: ./demo64: Permission denied
jack@jack-myheadache /media/jack/NASM/nasmfld $
2. understanding the parameters of wchgat
mov r8,0
mov rcx,COLOR_PAIR(BLACK_ON_WHITE)
mov rdx,0
mov rsi,len1
mov rdi,[hWindow]
call wchgat
Is my understanding of wchgat correct:
mov r8,0 =s const void *opts
mov rcx,COLOR_PAIR(BLACK_ON_WHITE) =s short color
mov rdx,0 =s attr_t_attr
mov rsi,len1 =s int n
mov rdi,[hWindow] =s Window *win
int wchgat(WINDOW *win, int n, attr_t attr,
short color, const void *opts)
Let me try to explain what I need for the demo64 program.
In Masm32 or Goasm you could vary colors by 250,000 ways.
I see in Nasm only color pairs that are very limited.
For instance the demo64 program screen has a faded out blue
a faded yellow rectangle. If the above wchgat is the way to solve
this then I need to understand how to fill out the instruction.
Where can I read more about this?
3. Where can I read about changing Fonts?
Is this part of the "ATTR"?
1. Still trying to get nasm to work on the separate HD.Code: [Select]jack@jack-myheadache /media/jack/NASM/nasmfld $ sudo chown -R jack /media/jack
[sudo] password for jack:
jack@jack-myheadache /media/jack/NASM/nasmfld $ nasm -f elf64 demo64.asm -o demo64.o
jack@jack-myheadache /media/jack/NASM/nasmfld $ gcc -o demo64 demo64.o -lcurses
jack@jack-myheadache /media/jack/NASM/nasmfld $ ./demo64
bash: ./demo64: Permission denied
jack@jack-myheadache /media/jack/NASM/nasmfld $
2. understanding the parameters of wchgatCode: [Select]mov r8,0
mov rcx,COLOR_PAIR(BLACK_ON_WHITE)
mov rdx,0
mov rsi,len1
mov rdi,[hWindow]
call wchgat
Is my understanding of wchgat correct:Code: [Select]mov r8,0 =s const void *opts
mov rcx,COLOR_PAIR(BLACK_ON_WHITE) =s short color
mov rdx,0 =s attr_t_attr
mov rsi,len1 =s int n
mov rdi,[hWindow] =s Window *winCode: [Select]int wchgat(WINDOW *win, int n, attr_t attr,
short color, const void *opts)
Let me try to explain what I need for the demo64 program.
In Masm32 or Goasm you could vary colors by 250,000 ways.
I see in Nasm only color pairs that are very limited.
For instance the demo64 program screen has a faded out blue
a faded yellow rectangle. If the above wchgat is the way to solve
this then I need to understand how to fill out the instruction.
Where can I read more about this?
Intensity | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Normal | Black | Red | Green | Yellow * | Blue | Magenta | Cyan | White |
Bright | Black | Red | Green | Yellow | Blue | Magenta | Cyan | White |
3. Where can I read about changing Fonts?
Is this part of the "ATTR"?
Hi Bryant,
As per your request:
#1
jack@jack-myheadache ~ $ sudo ls -al /media/jack/NASM/nasmfld
[sudo] password for jack:
total 1507
drwx------ 1 jack jack 4096 Mar 27 05:37 .
drwx------ 1 jack jack 4096 Mar 24 04:28 ..
-rw------- 1 jack jack 5408 Mar 6 16:42 Bryantscd
-rw------- 1 jack jack 4747 Mar 1 15:30 demo264.asm
-rw------- 1 jack jack 17354 Mar 27 05:37 demo64
-rw------- 1 jack jack 20093 Mar 26 16:53 demo64.asm
-rw------- 1 jack jack 12224 Mar 27 05:37 demo64.o
-rw------- 1 jack jack 42 Feb 29 07:32 demo64.sh
-rw------- 1 jack jack 942 Feb 19 16:38 hello
-rw------- 1 jack jack 457 Feb 19 16:37 hello.asm
-rw------- 1 jack jack 848 Feb 19 16:38 hello.o
-rw------- 1 jack jack 7568 Mar 7 08:33 lcurses
-rw------- 1 jack jack 12224 Mar 27 04:56 -lcurses
-rw------- 1 jack jack 592 Mar 7 08:21 LNInstructions.txt
drwx------ 1 jack jack 24576 Mar 8 11:40 nasm-2.11.08
-rw------- 1 jack jack 1398894 Feb 14 09:51 nasm-2.11.08.zip
-rw------- 1 jack jack 142 Mar 12 12:18 testnano.txt
-rw------- 1 jack jack 7493 Feb 22 16:10 tprt64c.asm
jack@jack-myheadache ~ $
#2 3-28-2016
HI Bryant,
hChildWindow dq 0
szUserInput db 0, 0, 0 ; don't understand this
;szUserInput db ' ',0 ; why not this way????
I have the same problem below no matter which way I
define szUserInput.
;; create 1st child window
mov rcx,50 ; x value
mov rdx,10 ; y value
mov rsi,3 ; 3 columns for 2 digits
mov rdi,1 ; 1 line for 1 row of digits
call newwin
mov [hChildWindow],rax
.g1:
mov rdx,2
mov rsi,szUserInput
mov rdi,[hChildWindow]
call wgetnstr ; reads 2 characters good or bad
Every time the user keys in a wrong digit I return to
.g1 and get new digits from the user. Whatever wrong
digits/characters the user keys in I get the same error
message on the screen. This is wrong. I am doing something
wrong!
Also, I don't understand the way szUserInput is defined?
oh my - #3 is going to keep me busy for months....
Code: [Select]jack@jack-myheadache ~ $ sudo ls -al /media/jack/NASM/nasmfld
[sudo] password for jack:
total 1507
drwx------ 1 jack jack 4096 Mar 27 05:37 .
drwx------ 1 jack jack 4096 Mar 24 04:28 ..
-rw------- 1 jack jack 5408 Mar 6 16:42 Bryantscd
-rw------- 1 jack jack 4747 Mar 1 15:30 demo264.asm
-rw------- 1 jack jack 17354 Mar 27 05:37 demo64
-rw------- 1 jack jack 20093 Mar 26 16:53 demo64.asm
-rw------- 1 jack jack 12224 Mar 27 05:37 demo64.o
-rw------- 1 jack jack 42 Feb 29 07:32 demo64.sh
-rw------- 1 jack jack 942 Feb 19 16:38 hello
-rw------- 1 jack jack 457 Feb 19 16:37 hello.asm
-rw------- 1 jack jack 848 Feb 19 16:38 hello.o
-rw------- 1 jack jack 7568 Mar 7 08:33 lcurses
-rw------- 1 jack jack 12224 Mar 27 04:56 -lcurses
-rw------- 1 jack jack 592 Mar 7 08:21 LNInstructions.txt
drwx------ 1 jack jack 24576 Mar 8 11:40 nasm-2.11.08
-rw------- 1 jack jack 1398894 Feb 14 09:51 nasm-2.11.08.zip
-rw------- 1 jack jack 142 Mar 12 12:18 testnano.txt
-rw------- 1 jack jack 7493 Feb 22 16:10 tprt64c.asm
jack@jack-myheadache ~ $
#2 3-28-2016
HI Bryant,
hChildWindow dq 0
szUserInput db 0, 0, 0 ; don't understand this
;szUserInput db ' ',0 ; why not this way????
I have the same problem below no matter which way I
define szUserInput.
;; create 1st child window
mov rcx,50 ; x value
mov rdx,10 ; y value
mov rsi,3 ; 3 columns for 2 digits
mov rdi,1 ; 1 line for 1 row of digits
call newwin
mov [hChildWindow],rax
.g1:
mov rdx,2
mov rsi,szUserInput
mov rdi,[hChildWindow]
call wgetnstr ; reads 2 characters good or bad
Every time the user keys in a wrong digit I return to
.g1 and get new digits from the user. Whatever wrong
digits/characters the user keys in I get the same error
message on the screen. This is wrong. I am doing something
wrong!
Also, I don't understand the way szUserInput is defined?
oh my - #3 is going to keep me busy for months....
[/code]
.g1:
mov rdx,2
mov rsi,szUserInput
mov rdi,[hChildWindow]
call wgetnstr ; reads 2 characters good or bad
mov al, byte [szUserInput]
cmp al, '0'
jb .err1
cmp al, '9'
ja .err1
mov al, byte [szUserInput+1]
cmp al, '0'
jb .err1
cmp al, '9'
ja .err1
jmp .out1
.err1:
;; do our error for invalid input.
;;
;; ...
;;
;; Okay, at this point you've done whatever invalid input message
;; you wanted to display to the user, but we now need to get the new
;; user input...
;; First we reinitialize the string
mov byte [szUserInput], 0
mov byte [szUserInput + 1], 0
;; Now we need to clear that window.
extern wclear ; add this to the top section where the other extern's are at.
mov rdi, [hChildWindow]
call wclear
;; Then we should jump back and let the user try entering the code again.
jmp .g1
.out1:
;; both characters read are decimal digits, convert
;; them to integers.
mov rdi, szUserInput
call atoi
Hi Bryant,
Perhaps I have keyed your instructions incorrectly?
jack@jack-myheadache /media/jack/NASM/nasmfld $ sudo chmod +x /media/jack/NASM/nasmfld/demo64
[sudo] password for jack:
jack@jack-myheadache /media/jack/NASM/nasmfld $ sudo ls -al /media/jack/NASM/nasmfld
total 1507
drwx------ 1 jack jack 4096 Mar 27 05:37 .
drwx------ 1 jack jack 4096 Mar 24 04:28 ..
-rw------- 1 jack jack 5408 Mar 6 16:42 Bryantscd
-rw------- 1 jack jack 4747 Mar 1 15:30 demo264.asm
-rw------- 1 jack jack 17354 Mar 27 05:37 demo64
-rw------- 1 jack jack 20093 Mar 26 16:53 demo64.asm
-rw------- 1 jack jack 12224 Mar 27 05:37 demo64.o
-rw------- 1 jack jack 42 Feb 29 07:32 demo64.sh
-rw------- 1 jack jack 942 Feb 19 16:38 hello
-rw------- 1 jack jack 457 Feb 19 16:37 hello.asm
-rw------- 1 jack jack 848 Feb 19 16:38 hello.o
-rw------- 1 jack jack 7568 Mar 7 08:33 lcurses
-rw------- 1 jack jack 12224 Mar 27 04:56 -lcurses
-rw------- 1 jack jack 592 Mar 7 08:21 LNInstructions.txt
drwx------ 1 jack jack 24576 Mar 8 11:40 nasm-2.11.08
-rw------- 1 jack jack 1398894 Feb 14 09:51 nasm-2.11.08.zip
-rw------- 1 jack jack 142 Mar 12 12:18 testnano.txt
-rw------- 1 jack jack 7493 Feb 22 16:10 tprt64c.asm
jack@jack-myheadache /media/jack/NASM/nasmfld $
Hi Bryant,
Posted as per your previous request.
mount directory : mount known device here
mount -t type dev dir : ordinary mount command
Note that one does not really mount a device, one mounts
a filesystem (of the given type) found on the device.
One can also mount an already visible directory tree elsewhere:
mount --bind olddir newdir
or move a subtree:
mount --move olddir newdir
One can change the type of mount containing the directory dir:
mount --make-shared dir
mount --make-slave dir
mount --make-private dir
mount --make-unbindable dir
One can change the type of all the mounts in a mount subtree
containing the directory dir:
mount --make-rshared dir
mount --make-rslave dir
mount --make-rprivate dir
mount --make-runbindable dir
A device can be given by name, say /dev/hda1 or /dev/cdrom,
or by label, using -L label or by uuid, using -U uuid .
Other options: [-nfFrsvw] [-o options] [-p passwdfd].
For many more details, say man 8 mount .
jack@jack-myheadache /media/jack/NASM $
I have a file of bitmaps.
How can I include them in the demo64 program and use them?
Hi Bryant,
Hope i got it right this time.....
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
none on /sys/fs/cgroup type tmpfs (rw)
none on /sys/fs/fuse/connections type fusectl (rw)
none on /sys/kernel/debug type debugfs (rw)
none on /sys/kernel/security type securityfs (rw)
udev on /dev type devtmpfs (rw,mode=0755)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=0620)
tmpfs on /run type tmpfs (rw,noexec,nosuid,size=10%,mode=0755)
none on /run/lock type tmpfs (rw,noexec,nosuid,nodev,size=5242880)
none on /run/shm type tmpfs (rw,nosuid,nodev)
none on /run/user type tmpfs (rw,noexec,nosuid,nodev,size=104857600,mode=0755)
none on /sys/fs/pstore type pstore (rw)
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev)
systemd on /sys/fs/cgroup/systemd type cgroup (rw,noexec,nosuid,nodev,none,name=systemd)
gvfsd-fuse on /run/user/1000/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,user=jack)
/dev/sda5 on /media/jack/NASM type fuseblk (rw,nosuid,nodev,allow_other,default_permissions,blksize=4096) [NASM]
/dev/sda7 on /media/jack/masm32 type fuseblk (rw,nosuid,nodev,allow_other,default_permissions,blksize=4096) [masm32]
jack@jack-myheadache /media/jack/NASM/nasmfld $
#1
HI Bryant,
The HD is always open as it is a windows drive.
jack@jack-myheadache /media/jack/NASM $ sudo umount /media/jack/NASM
[sudo] password for jack:
umount: /media/jack/NASM: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
jack@jack-myheadache /media/jack/NASM $
I don't want to be a pest about this so I think another approach
might be in order. How about me just keeping Nasm up to date on
the HD? I can work on the SSD with Linux and Nasm. Should either
one fail I can restore Linux from the DVD and Nasm from the HD.
Not what I want but doable.
#2
Should I try to update Nasm to the latest version 2.12.01.
The only way I could find out what version of Nasm I am running
is by looking at the zip file I downloaded. It is v2.11.08
#3
4-2-2016
I am trying to get the year, month and day.
Not sure if any of this is right.
extern time.h
struc tm
int tm.sec ; seconds ( 'INT" DO I NEED IT??)
int tm.min ; minutes
int tm.hour ; hours
int tm.mday ; day of the month
int tm.mon ; month
int tm.year ; year
int tm.wday ; day of the week
int tm.yday ; day in the year
int tm.isdst ; daylight saving time
endstruc
invoke GetLocalTime, addr tm ; 449
GetLocalTime is a Windows instruction
Don't know what to replace it with?
movzx eax,W[tm.year] ; 450
movzx ecx,W[tm.mon] ; 451
movzx ebx,W[tm.mday] ; 452
jack@jack-myheadache ~/nasmfld $ nasm -f elf64 demo64.asm -o demo64.o
demo64.asm:449: error: parser: instruction expected
demo64.asm:450: error: comma, colon or end of line expected
demo64.asm:451: error: comma, colon or end of line expected
demo64.asm:452: error: comma, colon or end of line expected
jack@jack-myheadache ~/nasmfld $
#1
HI Bryant,
The HD is always open as it is a windows drive.
jack@jack-myheadache /media/jack/NASM $ sudo umount /media/jack/NASM
[sudo] password for jack:
umount: /media/jack/NASM: device is busy.
(In some cases useful info about processes that use
the device is found by lsof(8) or fuser(1))
jack@jack-myheadache /media/jack/NASM $
I don't want to be a pest about this so I think another approach
might be in order. How about me just keeping Nasm up to date on
the HD? I can work on the SSD with Linux and Nasm. Should either
one fail I can restore Linux from the DVD and Nasm from the HD.
Not what I want but doable.
#2
Should I try to update Nasm to the latest version 2.12.01.
The only way I could find out what version of Nasm I am running
is by looking at the zip file I downloaded. It is v2.11.08
#3
4-2-2016
I am trying to get the year, month and day.
Not sure if any of this is right.
extern time.h
struc tm
int tm.sec ; seconds ( 'INT" DO I NEED IT??)
int tm.min ; minutes
int tm.hour ; hours
int tm.mday ; day of the month
int tm.mon ; month
int tm.year ; year
int tm.wday ; day of the week
int tm.yday ; day in the year
int tm.isdst ; daylight saving time
endstruc
invoke GetLocalTime, addr tm ; 449
GetLocalTime is a Windows instruction
Don't know what to replace it with?
movzx eax,W[tm.year] ; 450
movzx ecx,W[tm.mon] ; 451
movzx ebx,W[tm.mday] ; 452
jack@jack-myheadache ~/nasmfld $ nasm -f elf64 demo64.asm -o demo64.o
demo64.asm:449: error: parser: instruction expected
demo64.asm:450: error: comma, colon or end of line expected
demo64.asm:451: error: comma, colon or end of line expected
demo64.asm:452: error: comma, colon or end of line expected
jack@jack-myheadache ~/nasmfld $
;;; ntime.asm - displays the current time information.
BITS 64
GLOBAL main
%define STACK_ALIGN sub rsp, 8 ; stack adjustment for calling functions.
%define STACK_RESTORE add rsp, 8 ; restore previous stack alignment.
;;; Procedures from the standard C library.
EXTERN time
EXTERN localtime
EXTERN printf
;;; Data-type from the C time.h header.
STRUC tm
.tm_sec resd 1 ; Seconds (0-60)
.tm_min resd 1 ; Minutes (0-59)
.tm_hour resd 1 ; Hours (0-23)
.tm_mday resd 1 ; Day of the Month (1-31)
.tm_mon resd 1 ; Month (0-11)
.tm_year resd 1 ; Year - 1900
.tm_wday resd 1 ; Day of the week (0-6, Sunday = 0)
.tm_yday resd 1 ; Day in the year (0-365, 1 Jan = 0)
.tm_isdst resd 1 ; Daylight saving time
ENDSTRUC
SECTION .data ; Intialized data section.
now: dq 0 ; Storage for time since Epoch
plt: dq 0 ; Storage for pointer returned by localtime
SECTION .rodata ; Read-only data section.
strTime: db "The current time is %d:%d:%d", 10, 0
SECTION .text ; Executable data section.
;; main : number (string . string) -> number .
;; The application entrypoint (main) consumes an
;; argument count (argc) and a list of arguments
;; from the command line (argv) and produces an
;; error code for the operating system.
main:
STACK_ALIGN
;; Quote from (The Linux Programmer's Manual):
;; time() returns the time as the number of seconds since the
;; Epoc, 1970-01-01 00:00:00 +0000 (UTC).
;;
;; If `t' is non-NULL, the return value is also stored in the
;; memory pointed to by `t'.
mov rdi, now ; now = t
call time ; get time
;; Quote from (The Linux Programmer's Manual):
;; The localtime() function converts the calendar time `timep'
;; to broken-down time representation, expressed relative to the
;; user's specified timezone.
mov rdi, now ; timep = now
call localtime ; convert to localtime
mov [plt], rax ; save pointer to tm structure.
;; ... do some other stuff ...
mov rdi, [plt] ; get pointer to local tm structure.
movzx rcx, dword [rdi + tm.tm_sec] ; get second
movzx rdx, dword [rdi + tm.tm_min] ; get minute
movzx rsi, dword [rdi + tm.tm_hour] ; get hour
mov rdi, strTime ; show time
call printf
mov rax, 0 ; return EXIT_SUCCESS to Linux
STACK_RESTORE
ret
#1
4-3-2016
Hi Bryant,
I am trying to install nasm 2.12.01
Only place I can see to install NASM is in the zip
expansion "install".
It is only instructions to install which don't
work for me.
I renamed the previous nasmfld to nasmfld2.
Made another blank nasmfld.
jack@jack-myheadache ~/nasmfld $ sh autogen.sh
sh: 0: Can't open autogen.sh
jack@jack-myheadache ~/nasmfld $
#2
Does "resd 1" mean dword? What does the "1" do?
.tm_sec resd 1
#3
Everything I see talks about "printf" going to the screen.
I need to go to a hardware printer. Where can I read how to
do this?
#4
Can't find out how to draw lines from A to B.
This has nothing to do with macros.
Still looking....
#1
4-3-2016
Hi Bryant,
I am trying to install nasm 2.12.01
Only place I can see to install NASM is in the zip
expansion "install".
It is only instructions to install which don't
work for me.
I renamed the previous nasmfld to nasmfld2.
Made another blank nasmfld.
jack@jack-myheadache ~/nasmfld $ sh autogen.sh
sh: 0: Can't open autogen.sh
jack@jack-myheadache ~/nasmfld $
$ wget http://www.nasm.us/pub/nasm/releasebuilds/2.12.02rc1/nasm-2.12.02rc1.tar.gz
--2016-04-05 21:59:50-- http://www.nasm.us/pub/nasm/releasebuilds/2.12.02rc1/nasm-2.12.02rc1.tar.gz
Resolving www.nasm.us (www.nasm.us)... 198.137.202.10, 2001:1868:205::10
Connecting to www.nasm.us (www.nasm.us)|198.137.202.10|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1213813 (1.2M) [application/gzip]
Saving to: ‘nasm-2.12.02rc1.tar.gz’
nasm-2.12.02rc1.tar 100%[=====================>] 1.16M 159KB/s in 7.4s
2016-04-05 21:59:58 (160 KB/s) - ‘nasm-2.12.02rc1.tar.gz’ saved [1213813/1213813]
$ tar xvf nasm-2.12.02rc1.tar.gz
nasm-2.12.02rc1/
nasm-2.12.02rc1/preproc.h
nasm-2.12.02rc1/AUTHORS
... a bunch of other files...
$ cd nasm-2.12.02rc1/
nasm-2.12.02rc1$ ./configure && make && sudo make install
#2
Does "resd 1" mean dword? What does the "1" do?
.tm_sec resd 1
#3
Everything I see talks about "printf" going to the screen.
I need to go to a hardware printer. Where can I read how to
do this?
;; Printing text to hardware.
BITS 64
GLOBAL main
EXTERN popen
EXTERN pclose
EXTERN fprintf
EXTERN fflush
%define EXIT_SUCCESS 0
%define EXIT_FAILURE 1
%define STACK_ALIGN sub rsp, 8
%define STACK_RESTORE add rsp, 8
SECTION .rodata
szPrinter: db "lpr", 0
szWriteMode: db "w", 0
szSomeMessage: db "Hello, world!\nThis is a PDF!", 0
SECTION .data
fdPrinter: dq 0 ; our file descriptor.
SECTION .text
main: STACK_ALIGN
mov rsi, szWriteMode
mov rdi szPrinter
call popen
mov [fdPrinter], rax
cmp rax, 0
jnz .okay
mov rax, EXIT_FAILURE
STACK_RESTORE
ret
.okay:
mov rsi, szSomeMessage
mov rdi, [fdPrinter]
call fprintf
mov rdi, [fdPrinter]
call pclose
mov rax, EXIT_SUCCESS
STACK_RESTORE
ret
#4
Can't find out how to draw lines from A to B.
This has nothing to do with macros.
Still looking....
; size of array to hold the prime candidates
; (arraySize - 1) is the max prime candidate.
SECTION .data
arraySize EQU 10000
array1: dd arraySize dup(0) ; initialize array
.code
SECTION .text
extern printf
extern scanf
global main
main:
cls
xor ecx, ecx ; zeroing, is slightly faster than MOV reg, 0
fillArrayLoop:
mov eax, ecx ; Move counter value to eax
add eax, 2 ; The sieve starts at 2, therefore add 2 to the loop counter
mov [array1+4*ecx], eax ; Insert value into array
inc ecx ; Increment counter
cmp ecx, arraySize ;
jb fillArrayLoop ; jump below, Jump to loop start is we are not finished
xor ecx, ecx ; Zero out counter
loop1: ; This is out outer loop
mov ebx, ecx ; Prepare ebx to be used af counter in innerloop (loop2)
inc ebx ; Inner loop starts at ecx + 1
cmp [array1+4*ecx], -1 ; Value discarded? So is value -1?
jne loop2 ; if not jump to inner loop(loop2)
resume1: ; Resume point
inc ecx ; Increment out primary counter
cmp ecx, arraySize ; Are we done?
jb loop1 ; If not jump to loop start.
jmp theEnd ; All done!
loop2: ; Inner loop
cmp [array1+4*ebx], -1 ; Value discarded?
jne loop3 ; if nor jump to loop3
resume2: ; Resumt point
inc ebx ; Increment inner loop counter
cmp ebx, arraySize ; Are we done?
jb loop2 ; if not go to loop start.
jmp resume1 ; Loop2 dont, return to loop1.
loop3: ; Here we will test if it is a prime...
xor edx, edx ; Zero out edx
xor eax, eax ; Zero out eax
mov eax, [array1+4*ebx] ; Place the number we want to divite in eax
div [array1+4*ecx] ; Divide the numbe in eax with the value from outer loop
cmp edx, 0 ; Check edx for remainder
je nukeIt ; If we have no remainder it the number in eax is not a prime
; therefore we nuke it. (set it to -1)
resume3: ; Resume point
jmp resume2 ; Done, jump to resume point in loop2
nukeIt:
mov [array1+4*ebx], -1 ; Not a prime, set it to -1
jmp resume3 ; Jump to resume point
printArrayElement: ; Just printing all the primes.
push ecx ; Preserve ecx
print str$([array1+4*ecx]), 10, 13 ; Using the masm32 print macro
inc ebx ; Incrementing a counter used to store the number of primes.
pop ecx ; Callback the preserved ecx
jmp resumePrintArray ; Jump to resumepoint in print array.
theEnd: ; exit point
xor ecx, ecx ; Zero out.
xor ebx, ebx ; Zero out.
printArray:
cmp [array1+4*ecx], -1 ; Check if we have a prime.
jne printArrayElement ; If we have jump to printArrayElement.
resumePrintArray: ; Resume point
inc ecx ; Incrementing
cmp ecx, arraySize ; Are we done?
jb printArray ; If not jump to printArray...
print "Number of primes below "
print str$(arraySize)
print ": "
print str$(ebx), 10, 13
ret
nasm -f elf primes.asm && gcc -m32 -o primes primes.o
primes.asm:9: error: comma expected after operand 1
primes.asm:71: error: parser: instruction expected
primes.asm:91: error: symbol `print' redefined
primes.asm:91: error: parser: instruction expected
primes.asm:92: error: symbol `print' redefined
primes.asm:92: error: parser: instruction expected
primes.asm:93: error: symbol `print' redefined
primes.asm:93: error: parser: instruction expected
primes.asm:94: error: symbol `print' redefined
primes.asm:94: error: parser: instruction expected
section .data
array times arraySize dd 0
but might be better to do:section .bss
array resd arraySize
Programmer's choice. ("section .bss" is nominally uninitialized, but is, in fact, initialized to zero in any reasonable OS). Speaking of OS, Nasm's "-f elf" is for Linux. Your Masm code almost certainly is not. Is that what you intend? (no problem - we can do it either way... maybe both...)