;cmdl.asm
;command line arguments
;
section .data
;               define standard constants
;
LF equ 10 ;line feed,avanz.di riga,LF char.=EndOfLine
NULL equ         0     ;end of string
TRUE equ         1
FALSE equ        0
EXIT_SUCCESS equ 0
STDIN equ        0
STDOUT equ       1
STDERR equ       2
SYS_read equ     0
SYS_write equ    1
SYS_open equ     2
SYS_close equ    3
SYS_fork equ     57
SYS_exit equ     60    ;terminate
SYS_creat equ    85
SYS_time equ     201
;
; variables for main:
;
new_line db LF, NULL
;
section .text
global main
main:
; get command line arguments and echo to screen
; standard calling convention: 
; rdi = argc = argument count
; rsi = argv = starting address of argument vector
mov r12, rdi          ;save for later use
mov r13, rsi
;
; loop to display each argument to the screen
; each argument is a NULL terminated string, 
; so it can just print directly
;
print_arguments:
mov rdi, new_line
call print_string
;
mov rbx, 0
;
print_loop:
mov rdi, qword[r13+rbx*8]
call print_string
;
mov rdi, new_line
call print_string
;
inc rbx
cmp rbx, r12
jl print_loop     ; if rbx<r12 goto print_loop
;
FINITO:
mov rax, SYS_exit 
mov rdi, EXIT_SUCCESS
syscall
;
;
;
;
;
;
; generic procedure to display a string in the screen 
; String must be NULL terminated 
; Algorithm: 
; count characters in string (excluding NULL) 
; conta i caratteri eccetto NULL
; use syscall to output characters (emettere caratteri)
; Arguments: 1) address, string
; returns: nothing
;
global print_string
print_string:
push rbp
mov rbp, rsp
push rbx
;
; count characters in string
mov rbx, rdi
mov rdx, 0
str_count_loop:
cmp byte[rbx], NULL
je str_count_done
inc rdx
inc rbx
jmp str_count_loop
str_count_done:
cmp rdx, 0
je FINITO2 
;
; call OS to output string
mov rax, SYS_write           ;code for write()
mov rsi, rdi                 ;address of characters
mov edi, STDOUT              ;file descriptor   
;          
syscall
;
; string printed, return to calling routine 
;
FINITO2:
pop rbx
pop rbp
ret
