diff --git a/src/console.asm b/src/console.asm index 26fb55d..ad0cab1 100644 --- a/src/console.asm +++ b/src/console.asm @@ -10,6 +10,7 @@ section .rodata section .bss printfBuff resb printfBuffLen printfArgs resq 5 ;5=>rsi,rdx,rcx,r8,r9 + readsCBuff resb 1 section .text global __INTERNAL_fmt @@ -17,6 +18,7 @@ section .text global puts global printf global eprintf + global reads ;----- print(*str[]) -----; ; Prints given string to the console to stdout @@ -493,3 +495,51 @@ __INTERNAL_fmt: pop r12 leave ret + +;----- reads(*inputBuffer[], len) -----; +; Reads from console (stdin), stores input to inputBuffer[] +; ~~Return value: Amount of written characters (+EOS) to inputBuffer[] (so RAX-1 => amount of read characters)~~ +; Return value: Amount of read characters +; Used registers: +; rax* (ret) +; rdi* (arg) Pointer to inputBuffer[] +; rsi* (arg) Size of inputBuffer[] (or less to read less characters) +; rdx* arg for syscall +; r12 Stores inputBuffer[] +; r13 Stores len +; r14 Counts amount of read characters +reads: + push r12 + push r13 + push r14 + + lea r12, [rdi] + mov r13, rsi + dec r13 ;account for EOS + xor r14, r14 + + .readLoop: + mov rax, NR_read + mov rdi, FD_stdin + lea rsi, [rel readsCBuff] + mov rdx, 1 + syscall + + mov al, [readsCBuff] + cmp al, NL + je .finish + cmp r14, r13 + jae .readLoop ;Keep reading from stdin until \n is found as to flush stdin (too bad sys_lseek is not allowed on stdin, returns ESPIPE;illegal seek) + mov byte [r12], al + inc r12 + inc r14 + jmp .readLoop + + .finish: + mov byte [r12], EOS + mov rax, r14 + + pop r14 + pop r13 + pop r12 + ret diff --git a/src/tests.asm b/src/tests.asm index 5a0dd4b..e1c8ebd 100644 --- a/src/tests.asm +++ b/src/tests.asm @@ -77,6 +77,7 @@ extern print extern puts extern printf extern eprintf +extern reads ;string.asm extern strlen extern strcpy @@ -127,6 +128,7 @@ section .rodata TEST_puts equ 1 TEST_printf equ 1 TEST_eprintf equ 1 + TEST_reads equ 1 ;string.asm_ TEST_strlen equ 1 TEST_strcpy equ 1 @@ -273,6 +275,12 @@ section .rodata addTestHeader(_eprintf, "eprintf") addTest(eprintf1, "eprintf(''This is not an error :-)\n'')") eprintfStr1 db "This is not an error :-)\n",EOS + ;reads() + addTestHeader(_reads, "reads") + addTest(reads1, "reads(inputBuffer_4, 4) //input 3 or more characters to get OK result; abcdefg") + addTest(reads2, "reads(inputBuffer_32, 32) //input 31 or more characters to get OK result; abcdefghijklmnopqrstuvwxyz01234567890") + msg + msgReadBuffs db "\t### input buffers: (confirm OK):\n\tinputBuffer_4 (len=%d): %s\n\tinputBuffer_32 (len=%d): %s\n",EOS ; STRINGS FOR USE IN STRING FUNCTIOns str1 db "Hello, World!",EOS;13 str2 db "Hello, world!",EOS;13 @@ -415,6 +423,8 @@ section .rodata fgetmodStr db "\t- File permissions of file '%s': %04o\n",EOS section .bss + inputBuffer_4 resb 4 + inputBuffer_32 resb 32 strBuff1 resb 64 strBuff2 resb 64 fp1 resq 1 @@ -919,6 +929,39 @@ _start: assert_eq(25) %endif +;--- reads() +%if TEST_reads + printTestHeader(_reads) + + ; TEST 1: reads(inputBuffer_4, 4) + printTest(reads1) + lea rdi, [rel inputBuffer_4] + mov rsi, 4 + call reads + assert_eq(3) + + ; TEST 2: reads(inputBuffer_32, 32) + printTest(reads2) + lea rdi, [rel inputBuffer_32] + mov rsi, 32 + call reads + assert_eq(31) + + lea rdi, [rel inputBuffer_4] + call strlen + mov r10, rax + lea rsi, [rel inputBuffer_32] + call strlen + mov r11, rax + + lea rdi, [rel msgReadBuffs] + mov rsi, r10 + lea rdx, [rel inputBuffer_4] + mov rcx, r11 + lea r8, [rel inputBuffer_32] + call printf +%endif + ;;; ;;; STRINGS FOR STRING FUNCTIONS ;;;