Adds format(), modified __INTERNAL_fmt to allow writing to memory (instead of writing to given FD)
This commit is contained in:
109
src/console.asm
109
src/console.asm
@@ -1,6 +1,7 @@
|
||||
%include "src/constants.asm"
|
||||
|
||||
extern strlen
|
||||
extern strcat
|
||||
extern itoa
|
||||
extern utoa
|
||||
|
||||
@@ -88,6 +89,7 @@ puts:
|
||||
; \t Tab
|
||||
; Used registers:
|
||||
; rax* (ret) amount of printed characters
|
||||
; rbx Length of array being written to (if rax != FD)
|
||||
; rdi* (arg) pointer to format[] to format and print >> pointer to buffer
|
||||
; rsi* (optional arg) >> Used for inserting strings to buffer
|
||||
; rdx* (optional arg) >> misc
|
||||
@@ -181,7 +183,32 @@ __INTERNAL_fmt:
|
||||
jmp .insertString
|
||||
%endmacro
|
||||
|
||||
%macro check_formatted_len 2 ;check_format_len [return_label] [offset]
|
||||
test rbx, rbx
|
||||
jz %%checkBufferLen
|
||||
cmp r11, rbx
|
||||
jae .wrapup
|
||||
jmp .flushReturn_%1
|
||||
%%checkBufferLen:
|
||||
mov r9b, %1
|
||||
cmp r10, __fmt_BuffLen-%2
|
||||
je .flushBuffer
|
||||
.flushReturn_%1:
|
||||
%endmacro
|
||||
|
||||
%macro write_format_data 3 ;write_format_data [size] [offset] [what]
|
||||
test rbx, rbx
|
||||
jz %%writeToBuffer
|
||||
mov %1 [r15 + %2], %3
|
||||
jmp %%cnt
|
||||
%%writeToBuffer:
|
||||
mov %1 [__fmt_Buff + %2], %3
|
||||
%%cnt:
|
||||
%endmacro
|
||||
|
||||
; entry:
|
||||
test rax, rax
|
||||
js .start_fmt ;jump if signed; FD => Mem
|
||||
cmp rax, 0
|
||||
jg .start_fmt
|
||||
mov rax, -EBADF
|
||||
@@ -189,12 +216,20 @@ __INTERNAL_fmt:
|
||||
.start_fmt:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
sub rsp, SIZE_QWORD
|
||||
push rbx
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
mov r15, rax
|
||||
xor rbx, rbx
|
||||
test r15, r15
|
||||
jns .checkEmptyStr
|
||||
not r15
|
||||
mov rbx, [rbp + RBP_OFFSET_CALLER]
|
||||
|
||||
.checkEmptyStr:
|
||||
cmp byte [rdi], EOS
|
||||
je .emptyStr
|
||||
|
||||
@@ -213,16 +248,13 @@ __INTERNAL_fmt:
|
||||
.process:
|
||||
cmp byte [rdi], EOS
|
||||
je .wrapup
|
||||
xor r9b, r9b
|
||||
cmp r10, __fmt_BuffLen-1
|
||||
je .flushBuffer
|
||||
.flushReturn_0:
|
||||
check_formatted_len 0,1
|
||||
cmp byte [rdi], '\'
|
||||
je .asciiReplacement
|
||||
cmp byte [rdi], '%'
|
||||
je .argReplacement
|
||||
mov r8b, [rdi]
|
||||
mov [__fmt_Buff+r10], r8b
|
||||
write_format_data byte,r10,r8b
|
||||
inc r10
|
||||
inc r11
|
||||
inc rdi
|
||||
@@ -240,15 +272,10 @@ __INTERNAL_fmt:
|
||||
cmp byte [rdi + 1], 't'
|
||||
cmove r9, r8
|
||||
je .replaceAscii
|
||||
|
||||
jmp .invalidReplacement
|
||||
.replaceAscii:
|
||||
mov r8b, r9b
|
||||
mov r9b, 2
|
||||
cmp r10, __fmt_BuffLen-1
|
||||
je .flushBuffer
|
||||
.flushReturn_2:
|
||||
mov [__fmt_Buff + r10], r8b
|
||||
check_formatted_len 1, 1
|
||||
write_format_data byte,r10,r8b
|
||||
add rdi, 2
|
||||
inc r10
|
||||
inc r11
|
||||
@@ -342,7 +369,7 @@ __INTERNAL_fmt:
|
||||
cmp byte [rdi + 1], '\'
|
||||
je .invalidReplacement_specialChar; '%\n' would become "'%','\','n'" instead of "'%',EOS" when inserting full invalid specifier.
|
||||
mov r9w, word [rdi]
|
||||
mov [__fmt_Buff+r10], r9w
|
||||
write_format_data word,r10,r9w
|
||||
add rdi, 2
|
||||
add r10, 2
|
||||
add r11, 2
|
||||
@@ -350,7 +377,7 @@ __INTERNAL_fmt:
|
||||
jmp .process
|
||||
.invalidReplacement_specialChar:
|
||||
mov r9b, byte [rdi]
|
||||
mov [__fmt_Buff+r10], r9b
|
||||
write_format_data byte,r10,r9b
|
||||
inc rdi
|
||||
inc r10
|
||||
inc r11
|
||||
@@ -405,14 +432,10 @@ __INTERNAL_fmt:
|
||||
.insertString:
|
||||
test rsi, rsi
|
||||
jnz .doInsertString
|
||||
;rsi = NULL:
|
||||
mov r9b, 3
|
||||
cmp r10, __fmt_BuffLen-7
|
||||
je .flushBuffer
|
||||
.flushReturn_3:
|
||||
mov byte [__fmt_Buff + r10], '('
|
||||
mov qword [__fmt_Buff + r10 + 1], 'null'
|
||||
mov byte [__fmt_Buff + r10 + 5], ')'
|
||||
check_formatted_len 2, 7
|
||||
write_format_data byte,r10,'('
|
||||
write_format_data qword,r10+1,'null'
|
||||
write_format_data byte,r10+5,')'
|
||||
add r10, 6
|
||||
add r11, 6
|
||||
jmp .endInsertString
|
||||
@@ -420,12 +443,9 @@ __INTERNAL_fmt:
|
||||
.doInsertString:
|
||||
cmp byte [rsi], EOS
|
||||
je .endInsertString
|
||||
mov r9b, 1
|
||||
cmp r10, __fmt_BuffLen-1
|
||||
je .flushBuffer
|
||||
.flushReturn_1:
|
||||
check_formatted_len 3, 1
|
||||
mov r8b, byte [rsi]
|
||||
mov [__fmt_Buff + r10], r8b
|
||||
write_format_data byte,r10,r8b
|
||||
inc rsi
|
||||
inc r10
|
||||
inc r11
|
||||
@@ -438,7 +458,7 @@ __INTERNAL_fmt:
|
||||
|
||||
;--- Insert char to buffer ---;
|
||||
.insertChar:
|
||||
mov [__fmt_Buff + r10], sil
|
||||
write_format_data byte,r10,sil
|
||||
add rdi, 2
|
||||
add r10, 1
|
||||
add r11, 1
|
||||
@@ -447,6 +467,22 @@ __INTERNAL_fmt:
|
||||
jmp .process
|
||||
|
||||
.flushBuffer:
|
||||
test rbx, rbx
|
||||
jz .flush_print
|
||||
sub rsp, SIZE_QWORD
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
lea rdi, [r15]
|
||||
lea rsi, [rel __fmt_Buff]
|
||||
mov rdx, rbx
|
||||
call strcat
|
||||
pop rdx
|
||||
pop rsi
|
||||
pop rdi
|
||||
add rsp, SIZE_QWORD
|
||||
jmp .flush_ret
|
||||
.flush_print:
|
||||
push rdi
|
||||
push rsi
|
||||
push rdx
|
||||
@@ -463,7 +499,7 @@ __INTERNAL_fmt:
|
||||
test rax, rax
|
||||
js .quit
|
||||
xor r10, r10
|
||||
|
||||
.flush_ret:
|
||||
cmp r9b, 0
|
||||
je .flushReturn_0
|
||||
cmp r9b, 1
|
||||
@@ -474,6 +510,19 @@ __INTERNAL_fmt:
|
||||
je .flushReturn_3
|
||||
|
||||
.wrapup:
|
||||
test rbx, rbx
|
||||
jz .wrapup_print
|
||||
mov byte [r15+r10+1], EOS
|
||||
lea rdi, [r15]
|
||||
lea rsi, [rel __fmt_Buff]
|
||||
mov rdx, rbx
|
||||
sub rsp, SIZE_QWORD
|
||||
push r11
|
||||
call strcat
|
||||
pop rax
|
||||
add rsp, SIZE_QWORD
|
||||
jmp .quit
|
||||
.wrapup_print:
|
||||
mov rax, NR_write
|
||||
mov rdi, r15
|
||||
lea rsi, [rel __fmt_Buff]
|
||||
@@ -493,6 +542,8 @@ __INTERNAL_fmt:
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop rbx
|
||||
add rsp, SIZE_QWORD
|
||||
leave
|
||||
ret
|
||||
|
||||
|
@@ -1,5 +1,7 @@
|
||||
%include "src/constants.asm"
|
||||
|
||||
extern __INTERNAL_fmt
|
||||
|
||||
section .text
|
||||
global strlen
|
||||
global strcpy
|
||||
@@ -7,6 +9,7 @@ section .text
|
||||
global strclr
|
||||
global strcmp
|
||||
global strfind
|
||||
global format
|
||||
|
||||
;----- strlen(*str[]) -----;
|
||||
; Gets the length of given string
|
||||
@@ -216,3 +219,32 @@ strfind:
|
||||
mov rax, r8
|
||||
.quit:
|
||||
ret
|
||||
|
||||
;----- format(*dest[], len, *fmt[], ...) -----;
|
||||
; Formats a string and writes it to memory.
|
||||
; See __INTERNAL_fmt for valid specifiers
|
||||
; Return value: Amount of characters written to dest[]
|
||||
; Used registers:
|
||||
; rax* (ret)
|
||||
; rdi* (arg) Pointer to dest[]
|
||||
; rsi* (arg) Size of dest[]
|
||||
; rdx* (arg) Pointer to fmt[]
|
||||
format:
|
||||
push rbp
|
||||
mov rbp, rsp
|
||||
|
||||
mov rax, rdi
|
||||
not rax ;__INTERNAL_fmt; ~FD => Mem
|
||||
sub rsp, SIZE_QWORD
|
||||
push rsi ;__INTERNAL_fmt: pop len from stack if rax is signed
|
||||
lea rdi, [rdx]
|
||||
mov rsi, rcx
|
||||
mov rdx, r8
|
||||
mov rcx, r9
|
||||
mov r8, [rbp + RBP_OFFSET_CALLER + SIZE_QWORD * 0]
|
||||
mov r9, [rbp + RBP_OFFSET_CALLER + SIZE_QWORD * 1]
|
||||
call __INTERNAL_fmt
|
||||
add rsp, SIZE_QWORD * 2
|
||||
|
||||
leave
|
||||
ret
|
||||
|
Reference in New Issue
Block a user