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"
|
%include "src/constants.asm"
|
||||||
|
|
||||||
extern strlen
|
extern strlen
|
||||||
|
extern strcat
|
||||||
extern itoa
|
extern itoa
|
||||||
extern utoa
|
extern utoa
|
||||||
|
|
||||||
@@ -88,6 +89,7 @@ puts:
|
|||||||
; \t Tab
|
; \t Tab
|
||||||
; Used registers:
|
; Used registers:
|
||||||
; rax* (ret) amount of printed characters
|
; 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
|
; rdi* (arg) pointer to format[] to format and print >> pointer to buffer
|
||||||
; rsi* (optional arg) >> Used for inserting strings to buffer
|
; rsi* (optional arg) >> Used for inserting strings to buffer
|
||||||
; rdx* (optional arg) >> misc
|
; rdx* (optional arg) >> misc
|
||||||
@@ -181,7 +183,32 @@ __INTERNAL_fmt:
|
|||||||
jmp .insertString
|
jmp .insertString
|
||||||
%endmacro
|
%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:
|
; entry:
|
||||||
|
test rax, rax
|
||||||
|
js .start_fmt ;jump if signed; FD => Mem
|
||||||
cmp rax, 0
|
cmp rax, 0
|
||||||
jg .start_fmt
|
jg .start_fmt
|
||||||
mov rax, -EBADF
|
mov rax, -EBADF
|
||||||
@@ -189,12 +216,20 @@ __INTERNAL_fmt:
|
|||||||
.start_fmt:
|
.start_fmt:
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
|
sub rsp, SIZE_QWORD
|
||||||
|
push rbx
|
||||||
push r12
|
push r12
|
||||||
push r13
|
push r13
|
||||||
push r14
|
push r14
|
||||||
push r15
|
push r15
|
||||||
mov r15, rax
|
mov r15, rax
|
||||||
|
xor rbx, rbx
|
||||||
|
test r15, r15
|
||||||
|
jns .checkEmptyStr
|
||||||
|
not r15
|
||||||
|
mov rbx, [rbp + RBP_OFFSET_CALLER]
|
||||||
|
|
||||||
|
.checkEmptyStr:
|
||||||
cmp byte [rdi], EOS
|
cmp byte [rdi], EOS
|
||||||
je .emptyStr
|
je .emptyStr
|
||||||
|
|
||||||
@@ -213,16 +248,13 @@ __INTERNAL_fmt:
|
|||||||
.process:
|
.process:
|
||||||
cmp byte [rdi], EOS
|
cmp byte [rdi], EOS
|
||||||
je .wrapup
|
je .wrapup
|
||||||
xor r9b, r9b
|
check_formatted_len 0,1
|
||||||
cmp r10, __fmt_BuffLen-1
|
|
||||||
je .flushBuffer
|
|
||||||
.flushReturn_0:
|
|
||||||
cmp byte [rdi], '\'
|
cmp byte [rdi], '\'
|
||||||
je .asciiReplacement
|
je .asciiReplacement
|
||||||
cmp byte [rdi], '%'
|
cmp byte [rdi], '%'
|
||||||
je .argReplacement
|
je .argReplacement
|
||||||
mov r8b, [rdi]
|
mov r8b, [rdi]
|
||||||
mov [__fmt_Buff+r10], r8b
|
write_format_data byte,r10,r8b
|
||||||
inc r10
|
inc r10
|
||||||
inc r11
|
inc r11
|
||||||
inc rdi
|
inc rdi
|
||||||
@@ -240,15 +272,10 @@ __INTERNAL_fmt:
|
|||||||
cmp byte [rdi + 1], 't'
|
cmp byte [rdi + 1], 't'
|
||||||
cmove r9, r8
|
cmove r9, r8
|
||||||
je .replaceAscii
|
je .replaceAscii
|
||||||
|
|
||||||
jmp .invalidReplacement
|
jmp .invalidReplacement
|
||||||
.replaceAscii:
|
.replaceAscii:
|
||||||
mov r8b, r9b
|
check_formatted_len 1, 1
|
||||||
mov r9b, 2
|
write_format_data byte,r10,r8b
|
||||||
cmp r10, __fmt_BuffLen-1
|
|
||||||
je .flushBuffer
|
|
||||||
.flushReturn_2:
|
|
||||||
mov [__fmt_Buff + r10], r8b
|
|
||||||
add rdi, 2
|
add rdi, 2
|
||||||
inc r10
|
inc r10
|
||||||
inc r11
|
inc r11
|
||||||
@@ -342,7 +369,7 @@ __INTERNAL_fmt:
|
|||||||
cmp byte [rdi + 1], '\'
|
cmp byte [rdi + 1], '\'
|
||||||
je .invalidReplacement_specialChar; '%\n' would become "'%','\','n'" instead of "'%',EOS" when inserting full invalid specifier.
|
je .invalidReplacement_specialChar; '%\n' would become "'%','\','n'" instead of "'%',EOS" when inserting full invalid specifier.
|
||||||
mov r9w, word [rdi]
|
mov r9w, word [rdi]
|
||||||
mov [__fmt_Buff+r10], r9w
|
write_format_data word,r10,r9w
|
||||||
add rdi, 2
|
add rdi, 2
|
||||||
add r10, 2
|
add r10, 2
|
||||||
add r11, 2
|
add r11, 2
|
||||||
@@ -350,7 +377,7 @@ __INTERNAL_fmt:
|
|||||||
jmp .process
|
jmp .process
|
||||||
.invalidReplacement_specialChar:
|
.invalidReplacement_specialChar:
|
||||||
mov r9b, byte [rdi]
|
mov r9b, byte [rdi]
|
||||||
mov [__fmt_Buff+r10], r9b
|
write_format_data byte,r10,r9b
|
||||||
inc rdi
|
inc rdi
|
||||||
inc r10
|
inc r10
|
||||||
inc r11
|
inc r11
|
||||||
@@ -405,14 +432,10 @@ __INTERNAL_fmt:
|
|||||||
.insertString:
|
.insertString:
|
||||||
test rsi, rsi
|
test rsi, rsi
|
||||||
jnz .doInsertString
|
jnz .doInsertString
|
||||||
;rsi = NULL:
|
check_formatted_len 2, 7
|
||||||
mov r9b, 3
|
write_format_data byte,r10,'('
|
||||||
cmp r10, __fmt_BuffLen-7
|
write_format_data qword,r10+1,'null'
|
||||||
je .flushBuffer
|
write_format_data byte,r10+5,')'
|
||||||
.flushReturn_3:
|
|
||||||
mov byte [__fmt_Buff + r10], '('
|
|
||||||
mov qword [__fmt_Buff + r10 + 1], 'null'
|
|
||||||
mov byte [__fmt_Buff + r10 + 5], ')'
|
|
||||||
add r10, 6
|
add r10, 6
|
||||||
add r11, 6
|
add r11, 6
|
||||||
jmp .endInsertString
|
jmp .endInsertString
|
||||||
@@ -420,12 +443,9 @@ __INTERNAL_fmt:
|
|||||||
.doInsertString:
|
.doInsertString:
|
||||||
cmp byte [rsi], EOS
|
cmp byte [rsi], EOS
|
||||||
je .endInsertString
|
je .endInsertString
|
||||||
mov r9b, 1
|
check_formatted_len 3, 1
|
||||||
cmp r10, __fmt_BuffLen-1
|
|
||||||
je .flushBuffer
|
|
||||||
.flushReturn_1:
|
|
||||||
mov r8b, byte [rsi]
|
mov r8b, byte [rsi]
|
||||||
mov [__fmt_Buff + r10], r8b
|
write_format_data byte,r10,r8b
|
||||||
inc rsi
|
inc rsi
|
||||||
inc r10
|
inc r10
|
||||||
inc r11
|
inc r11
|
||||||
@@ -438,7 +458,7 @@ __INTERNAL_fmt:
|
|||||||
|
|
||||||
;--- Insert char to buffer ---;
|
;--- Insert char to buffer ---;
|
||||||
.insertChar:
|
.insertChar:
|
||||||
mov [__fmt_Buff + r10], sil
|
write_format_data byte,r10,sil
|
||||||
add rdi, 2
|
add rdi, 2
|
||||||
add r10, 1
|
add r10, 1
|
||||||
add r11, 1
|
add r11, 1
|
||||||
@@ -447,6 +467,22 @@ __INTERNAL_fmt:
|
|||||||
jmp .process
|
jmp .process
|
||||||
|
|
||||||
.flushBuffer:
|
.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 rdi
|
||||||
push rsi
|
push rsi
|
||||||
push rdx
|
push rdx
|
||||||
@@ -463,7 +499,7 @@ __INTERNAL_fmt:
|
|||||||
test rax, rax
|
test rax, rax
|
||||||
js .quit
|
js .quit
|
||||||
xor r10, r10
|
xor r10, r10
|
||||||
|
.flush_ret:
|
||||||
cmp r9b, 0
|
cmp r9b, 0
|
||||||
je .flushReturn_0
|
je .flushReturn_0
|
||||||
cmp r9b, 1
|
cmp r9b, 1
|
||||||
@@ -474,6 +510,19 @@ __INTERNAL_fmt:
|
|||||||
je .flushReturn_3
|
je .flushReturn_3
|
||||||
|
|
||||||
.wrapup:
|
.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 rax, NR_write
|
||||||
mov rdi, r15
|
mov rdi, r15
|
||||||
lea rsi, [rel __fmt_Buff]
|
lea rsi, [rel __fmt_Buff]
|
||||||
@@ -493,6 +542,8 @@ __INTERNAL_fmt:
|
|||||||
pop r14
|
pop r14
|
||||||
pop r13
|
pop r13
|
||||||
pop r12
|
pop r12
|
||||||
|
pop rbx
|
||||||
|
add rsp, SIZE_QWORD
|
||||||
leave
|
leave
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
%include "src/constants.asm"
|
%include "src/constants.asm"
|
||||||
|
|
||||||
|
extern __INTERNAL_fmt
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
global strlen
|
global strlen
|
||||||
global strcpy
|
global strcpy
|
||||||
@@ -7,6 +9,7 @@ section .text
|
|||||||
global strclr
|
global strclr
|
||||||
global strcmp
|
global strcmp
|
||||||
global strfind
|
global strfind
|
||||||
|
global format
|
||||||
|
|
||||||
;----- strlen(*str[]) -----;
|
;----- strlen(*str[]) -----;
|
||||||
; Gets the length of given string
|
; Gets the length of given string
|
||||||
@@ -216,3 +219,32 @@ strfind:
|
|||||||
mov rax, r8
|
mov rax, r8
|
||||||
.quit:
|
.quit:
|
||||||
ret
|
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