	;; NASM program to read from cmd line arg, open file, read first line, and print first line to screen
	;;	Uses fopen, fscanf, and printf
	;; For help using the stack to write subroutines, consult the assembly lecture "Stack Basics and Procedure Calls"

	;; nasm -f elf cfunctions.asm
	;; gcc cfunctions.o
	;; a.out input.txt
	
	
%include "mine.inc"
	
extern printf
extern fopen
extern fscanf

%define STDIN 0
%define STDOUT 1
%define SYSCALL_EXIT  1
%define SYSCALL_READ  3
%define SYSCALL_WRITE 4

	
global main

section .data
		
read_char:	db 'r', 0
format:		db "%d",10,0
filename:	dd 0
file_pointer:	dd 0
number:		dd 0
string:	        db "The integer is %d",10,0	
	
section .text

main:

	;; Get the filename, pointer to input filename is returned, will equal 0 for an invalid filname
	push	dword filename	; Push address of the pointer to the filename
	call	GetCommandLine	; Return address pushed to stack, Go to line 72, GetCommandLine
	add	esp, 4		; Resets stack value (equivalent to 'pop' inst)

	;; (You need to insert code here to error check filename)
	
	;; Open the file using fopen
	;; Equivalent to eax = fopen("input.txt", "r") if programmed in C
	push    dword read_char	; "r" to open a file for reading
	push    dword [filename] ; filename from cmd line arg
	call    fopen
	add     esp, 8

	;; Error check fstream returned from fopen
	cmp	eax, 0
	je	Exit		
	mov	[file_pointer], eax

	;; Read a value from the file using fscanf
	push	dword number	; Address of 'number'
	push    dword format	; %d to read an integer
	push    dword [file_pointer] ; fstream from fopen
	call    fscanf
	add     esp, 12

	;; Print first line from file
	push    dword [number]
	push    dword string
	call    printf
	add     esp, 8
	

Exit:	
	mov     EAX, SYSCALL_EXIT       
        mov     EBX, 0                
        int     080h                    
	ret		

GetCommandLine:

	;; Macros to move esp into ebp and push regs to be saved
         Enter 0
         Push_Regs ebx, ecx, edx

	;; Initially sets [filename] to 0, remains 0 if there's an error
         mov ebx, [ebp + 8]
         mov [ebx], dword 0

	;; Get argc (# of arguments)
         mov ecx, [ebp + 16]

	;; Checks the value of argc, should be 2 (a.out and input.txt), includes the if statement macro
         cmp ecx, 2
         if ne
            jmp gcl_done
         endif

	;; Get argv[0] ("a.out"/"cfunctions" or the executable, this is not used in the project)
	;; Consult slide 6 of Stack Basics... lecture
	 mov ecx, [ebp + 20]   	;  ptr to args ptr
	 mov ebx, [ecx]		;  argv[0]

	;; Get argv[1] ("input.txt")
         mov ecx, [ebp + 20]	; ptr to args ptr
         mov ebx, [ecx + 4]	; argv[1]

	;; Set the filename pointer arg on the stack to the address of the filename
         mov edx, [ebp + 8]
         mov [edx], ebx

gcl_done:
	;; Macros to return
         Pop_Regs ebx, ecx, edx
         Leave

	;; Return
         ret