__INTERNAL_fmt: Add description + return with errno -EBADF if FD is lower than FD_stdout (1)

This commit is contained in:
2025-07-26 00:50:09 +02:00
parent fdef1ed7b6
commit 8a18695328

View File

@@ -101,6 +101,16 @@ printf:
mov rax, FD_stdout mov rax, FD_stdout
jmp __INTERNAL_fmt jmp __INTERNAL_fmt
;----- __INTERNAL_fmt(*format[], ...) -----;
; See printf description above, +
; 1) Return value can be amount of printed characters or -errno (eg if bad FD was passed, -EBADF is returned)
; 2) FD has to be passed via RAX (this is clearly an INTERNAL function so passed arguments are slightly different, that is, RAX required for FD)
; 3) <!> <!> FOR DEVS: When writing an I/O function that calls this wrapper, make sure that:
; - That function has function prologue (ie push rbp + mov rbp, rsp)
; - __INTERNAL_fmt is called via CALL and not a simple JMP like in printf
; This is because in such I/O functions, first argument should be file descriptor, and following SYS V ABI, that first argument is passed to RDI
; However since __INTERNAL_fmt expects FD via RAX, all arguments have to be shifted. Due to this, argument in R9 becomes a stack argument
; Because of that, __INTERNAL_fmt has to load from stack with a different offset; +24 bytes extra (extra +8 for function call, extra +8 for function prologue and extra +8 to account for possible R9 arg becoming a stack arg)
__INTERNAL_fmt: __INTERNAL_fmt:
%macro load_arg 1 %macro load_arg 1
cmp r14, 4 cmp r14, 4
@@ -162,6 +172,11 @@ __INTERNAL_fmt:
%endmacro %endmacro
; entry: ; entry:
cmp rax, 0
jg .start_fmt
mov rax, -EBADF
ret
.start_fmt:
push rbp push rbp
mov rbp, rsp mov rbp, rsp
push r12 push r12