Author Topic: beginner questions  (Read 93642 times)

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #30 on: February 22, 2016, 09:40:13 PM »
the 686 was 32-bit also.. check out The NASM Manual - CPU Directive. I think what you'll need is CPU IA64, though you could probably just remove that line.

About Bryant Keller
bkeller@about.me

Offline jackjps

  • Jr. Member
  • *
  • Posts: 60
Re: beginner questions
« Reply #31 on: February 22, 2016, 09:55:03 PM »
Got a clean compile.
I ran gcc -o demo64 demo64.o -lcurses
Have no idea what this is supposed to do.
Does it replace  ld -o demo64 demo54.o?
How do I run the program???????

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #32 on: February 22, 2016, 10:08:48 PM »
I used gcc instead of ld because it's easier and I'm kinda lazy. The -o option specifies your output file. 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.

About Bryant Keller
bkeller@about.me

Offline jackjps

  • Jr. Member
  • *
  • Posts: 60
Re: beginner questions
« Reply #33 on: February 22, 2016, 10:50:35 PM »
nope. That gave me a segmentation fault.

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #34 on: February 22, 2016, 11:08:48 PM »
Did you actually convert it to 64-bit code or just change the registers? The new calling convention is very different.

About Bryant Keller
bkeller@about.me

Offline jackjps

  • Jr. Member
  • *
  • Posts: 60
Re: beginner questions
« Reply #35 on: February 23, 2016, 12:26:53 AM »
Took out to save space.
« Last Edit: February 23, 2016, 12:17:12 PM by jackjps »

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #36 on: February 23, 2016, 12:57:27 AM »
You got to read the tutorial, the calling convention was changed to use registers and stack alignment is a big issue.

I have no way of testing this code, but this is a rough translation if you want to try and build it.

Code: (demo64.asm) [Select]
; 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

Let me know if it works... technically this will have been my first IA64 application. ;D
« Last Edit: February 23, 2016, 01:02:42 AM by Bryant Keller »

About Bryant Keller
bkeller@about.me

Offline jackjps

  • Jr. Member
  • *
  • Posts: 60
Re: beginner questions
« Reply #37 on: February 23, 2016, 12:21:47 PM »
Getting compile errors with this.
undefined reference to all the "C" functions
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 $


;------------------------------------------------
;   2-23-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 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

section .text
    global _start    ;??
_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
   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

;; 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



 
« Last Edit: February 23, 2016, 06:25:07 PM by jackjps »

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #38 on: February 24, 2016, 12:31:05 AM »
In 64-bit shouldn't all the calls be changed to "syscall"???

The syscall instruction invokes an operating system routine, sorta like how on 32-bit systems you do so with the int instruction. What we are doing is invoking procedures that are present in a shared library, so we need to use call instead. Just like in Win32, when you want to use CreateFile or some other procedure, you use the call instruction instead of int 0x2E operating system service directly.

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????

Actually, I am using registers. This is some of that weirdness that they did to the calling convention that Frank and I was talking about. The new convention is to put values in registers so you can call procedures faster. However, the stack pointer must be aligned on a 16-byte value before you make a call. That sounds fine, except that call pushes the return address onto the stack (an 8-byte value) so if you're aligned before a call, your unaligned in the routine. What I do here is, at the start of each subroutine I realign the stack back to a 16-byte boundary and before each ret I restore stack pointer so that the return address is back in place. This craziness is a total waste of memory but is something that Intel thought was a good idea. This isn't a Linux thing, Windows has to do the same thing (except they also require shadow space which is like backup stack space for registers....)

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

I've actually never seen this error before, it might be worth it to find someone more experienced with 64-bit development to explain that. Those errors are referring to something in the C runtime, but aside from that.... I dunno what to make of it.

EDIT:
I just noticed you modified the code I posted. You don't need global _start and _start: in your code. The _start label is used internally, because you're making use of the C library, there are some initialization routines that need to be setup for you. In the original example, our entry point is at main which is a function called by the standard C library after that initialization. Remove those two lines and try again. I think that's what is causing it.

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 $

Now these errors I'm familiar with. The problem here is that ncurses isn't being linked in and so ld can't find those functions. In fact, given the command line you posted, I'm surprised you're not getting more errors. The reason people tend to use GCC instead of LD directly is because GCC will search for and find the startup routines and libraries you need. On my 32-bit Linux system, I can link the original 32-bit demo.o with the command:

Code: [Select]
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
This is considerably longer than the alternative GCC form of:

Code: [Select]
gcc -o demo demo.o -lcurses
As you can see, I'm referencing crti.o, crt1.o, crtn.o and ld-linux.so.2... however, these aren't always installed in the same place on your system. That's why GCC is so useful, it'll find those files for you. I recommend using it instead of LD directly.


About Bryant Keller
bkeller@about.me

Offline jackjps

  • Jr. Member
  • *
  • Posts: 60
Re: beginner questions
« Reply #39 on: February 24, 2016, 02:44:42 AM »
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. 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....



« Last Edit: February 24, 2016, 02:55:32 AM by jackjps »

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #40 on: February 24, 2016, 06:08:49 AM »
Thanks Bryant,
I took out global_start and _start.
Everything worked :)

Congrats to both of us then. You got it working and I've done my first working 64-bit program.  ;)

Got a light blue screen and a light yellow rectangle.
It accepted  4 digits.

Yep, that's pretty much the use case you mentioned. I hope it's enough of a starting point from you to learn more from. If you have any other questions, don't hesitate to ask. We are always glad to help.

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.

I don't think you can delete your old post after it's been replied too after a certain amount of time. Leave it, it'll be useful for others who follow in your footsteps to see the progression of the conversation.

The blue screen takes up about 1/4 of the screen and should be
the entire screen.

Not sure why it's doing that, the 32-bit one fills the entire screen on mine. I've tested in both xfce4-terminal and xterm. The only issues I've had has been that xfce4-terminal messes up the colors a little, but that can be adjusted with modifying the preferences.

Would like a lighter blue. The yellow rectangle
needs to be a brighter yellow.

There are various text attributes you can change (underline, bold, blink, etc) but my knowledge and use of curses is fairly limited. Most of that information can be gleamed from looking through the C header curses.h but (as with most portability projects) there are a lot of macros involved in making the system portable and it can be difficult to wade through sometimes. A lot of times to save myself the trouble of hunting through macros to find out a value, I'll just write a simple C program that includes the header and uses printf to display the resulting number, for example if I read the manual pages and find out that you can set a bold attribute of a window by giving the wattron option the A_BOLD value, I can find out what value I should set A_BOLD to by writing up this quick C program:

Code: (bold.c) [Select]
#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
$

This is the exact line we would put into our NASM source (or possibly a header to be included in our source) to allow us to use A_BOLD.

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.

To create the rectangle I get the users text from, i created a child window. During that windows creation, I set it's coordinates on the screen. I put comments explaining what each of the arguments were for that, search the source for line containing call newwin, above that I setup the parameters and put comments in place describing what the values mean. You should compare that to the man page for newwin.

The ncurses library provides you with a function for moving the windows cursor called wmove and a function for writing text on the screen called waddnstr. You could easily do what you want with those.

Just to get you ahead of the game, what you're actually describing would be accomplished using the ncurses forms library. Right now, I would suggest just getting good at the basics of 64-bit Linux Assembly then worry about doing more advanced interfaces. However, if you decide to really get into this ncurses stuff. The following tutorial will help you tremendously.

NCURSES Programming HOWTO

The NCURSES Forms library allows you to create the label and field style input you're leading up to.

I am hoping your example will give me enough NASM knowledge
to do the other 199 programs I need to convert.

Sounds like quite the code base to work on. Lots of opportunity for refining your skills in the Linux environment. :)

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....

Well, i don't have meteorite insurance, but I keep most of my backups on USB disk or SD cards. I've got quite a few of both in my desk drawer. If you're looking for public code management, you can always use SVN or GIT and a hosted repository like SourceForge or GitHub. The NASM project itself is hosted on a GIT repository called repo.or.cz. Managing your project with these tools are a good idea, though a bit complicated to use if you're not used to version control systems (VCS). I'm only just now getting used to using them, sad since a few projects I've been involved with have used both.  :-[

About Bryant Keller
bkeller@about.me

Offline jackjps

  • Jr. Member
  • *
  • Posts: 60
Re: beginner questions
« Reply #41 on: February 24, 2016, 11:31:44 AM »
Thanks again Bryant,
It will take a bunch of time to wade through your last post
and read the ncurses howto.

OK, I won't delete my last long post.
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?

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #42 on: February 24, 2016, 12:43:30 PM »
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?

That "scrolling goodie" is called a code block. There are two ways to do it. When your editing a post, there are a number of formatting buttons above the text area that you type in. Once you've entered your code into the text area, highlight the text by selecting it, then click the button marked with a # character. This will wrap the code you entered in the proper code tags. The second way is to enter them manually, for example:

[CODE]This is source code[/CODE]

Will create the following:

Code: [Select]
This is source code
If your code is really long, the code block will add a scrollbar to save on visible space. What's even more important is that the code block formats your code in a fixed with font, this means that code is easier to read. To be honest, of all the formatting features available on these forums, the code blocks are by far the most useful and should be used as much as possible. ;D

About Bryant Keller
bkeller@about.me

Offline jackjps

  • Jr. Member
  • *
  • Posts: 60
Re: beginner questions
« Reply #43 on: February 24, 2016, 06:52:48 PM »
Code: [Select]
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.
« Last Edit: February 26, 2016, 02:57:37 PM by jackjps »

Offline Bryant Keller

  • Forum Moderator
  • Full Member
  • *****
  • Posts: 360
  • Country: us
    • About Bryant Keller
Re: beginner questions
« Reply #44 on: February 26, 2016, 07:56:14 PM »
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?

These links should be kept if you do NCURSES development.

NCURSES Manual
NCURSE Frequently Asked Questions
GNU's NCURSES page

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.

Unlike on Windows, the terminal window is just another application, you can actually remove them and install different ones if you want (xterm, eterm, rxvt, xfce4-terminal, gnome-terminal, etc.). Your graphical environment and console mode applications aren't tied together and if you run a console mode program, the system won't just swap to a console and take over the screen. Console applications need to be specifically launched in a terminal (or from a terminal). If you want fullscreen mode, try my suggestion on the other forum. You'll need to switch between consoles using the ALT+CTRL+Fn keys.

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
;   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.

The reason it didn't work is because that line has nothing to do with the background window. There are actually 2 windows at play in that example. The standard screen (stdscr) is the root window and it is created by:

Code: [Select]
   ;; 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

I saved a copy of the stdscr handle in memory located at hWindow. The child window created by newwin is the rectangle than is holding the 4 characters you're inputing.

I'm not sure why you're not getting the proper display height/width. The stdscr is supposed to be automatically set to your terminal dimensions. This honestly sounds like a bug in your terminal emulator, try running xterm and test the program in that terminal emulator. If you don't have xterm or the command redirects to another terminal (some distro's do that, I hate that) then try it from the console (which I think you were going to do anyway).

Quote from: "shankle (MasmForum)" date=1456488181
On the NASM forum i'm lucky if I get 1 response per day to my questions.

One of the reasons you don't get immediate answers is because your posts are spread out, you're talking on two different forums across (so far) 3 different threads and your responses assume that everyone is able to follow you. This isn't the case. I rarely get on MasmForum except to message friends from the old AsmCommunity site. That said, if you're going to cross post, make sure you give all relevant information to your post. For example, your post on MasmForum doesn't explain what demo64 is, you just assume the people there know what your talking about, that's why I was the only one to respond. It's hard for anyone to answer questions when all the information isn't there.

Quote from: "shankle (MasmForum)" date=1456488181
With no books to study about the language and erroneous, outdated and
hard to find solutions, one wonders how anyone can program in NASM.

True, most books referring to Assembly Language target the 32-bit platform. With all the information targeting the 32-bit architecture, people find it easier to just start there using 32-bit environments in virtual machines or using backward compatibility mode, then later on (after they've gained basic programming skills) learn the conventions for 64-bit architectures from the Intel manual's.
« Last Edit: February 26, 2016, 08:00:47 PM by Bryant Keller »

About Bryant Keller
bkeller@about.me