mirror of
https://github.com/Noratrieb/asm-coreutils.git
synced 2026-01-14 09:45:04 +01:00
add itoa and build "system"
This commit is contained in:
parent
73c1ca8415
commit
19427394db
3 changed files with 153 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
target
|
||||
.idea
|
||||
*.iml
|
||||
30
build.sh
Normal file
30
build.sh
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
build () {
|
||||
FILE="$1"
|
||||
PROGRAM_NAME=$(basename "$FILE" ".asm")
|
||||
|
||||
if [ ! -f "$FILE" ]; then
|
||||
echo "$PROGRAM_NAME not found"
|
||||
return
|
||||
fi
|
||||
|
||||
echo "Building $PROGRAM_NAME"
|
||||
nasm -g -F dwarf -f elf64 "$FILE" -o "./target/$PROGRAM_NAME.o" && ld.lld "./target/$PROGRAM_NAME.o" -o "./target/$PROGRAM_NAME"
|
||||
}
|
||||
|
||||
|
||||
if [ "$1" = "--clean" ]; then
|
||||
rm -r target
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ ! -d ./target ]; then
|
||||
mkdir ./target
|
||||
fi
|
||||
|
||||
if [ "$#" -eq 0 ]; then
|
||||
for FILE in ./src/*.asm ; do
|
||||
build "$FILE"
|
||||
done
|
||||
else
|
||||
build "src/$1.asm"
|
||||
fi
|
||||
120
src/itoa.asm
Normal file
120
src/itoa.asm
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
global _start
|
||||
|
||||
NUMBER EQU 0
|
||||
|
||||
section .data
|
||||
buffer: times 8 db 0
|
||||
|
||||
|
||||
section .text
|
||||
_start:
|
||||
mov rax, NUMBER
|
||||
mov rbx, buffer
|
||||
call itoa
|
||||
cmp rax, 0
|
||||
jnz error
|
||||
|
||||
write_buffer:
|
||||
mov rax, 1 ; write
|
||||
mov rdi, 1 ; stdout
|
||||
mov rsi, buffer
|
||||
mov rdx, rbx ; the length
|
||||
syscall
|
||||
|
||||
graceful_exit:
|
||||
xor rdi, rdi
|
||||
jmp exit
|
||||
|
||||
error:
|
||||
mov rdi, 1
|
||||
exit:
|
||||
mov rax, 60
|
||||
syscall
|
||||
|
||||
|
||||
|
||||
; itoa - converts an unsigned integer into its ascii representation
|
||||
; inputs:
|
||||
; rax - the number
|
||||
; rbx - the pointer to the buffer
|
||||
; outputs:
|
||||
; rax - 0: success, 1: error
|
||||
; rbx - the length
|
||||
|
||||
MAX_SIZE EQU 100000
|
||||
START_DIVISOR EQU MAX_SIZE / 10
|
||||
ASCII_NUM EQU 48
|
||||
|
||||
itoa:
|
||||
; r12: whether we are in the leading zeroes (bool)
|
||||
; r11: buffer start
|
||||
; r10: number
|
||||
; r9: divisor
|
||||
; r8: current buffer pointer
|
||||
mov r12, 1
|
||||
mov r10, rax
|
||||
|
||||
cmp r10, MAX_SIZE
|
||||
jge number_too_big
|
||||
|
||||
mov r9, START_DIVISOR
|
||||
mov r11, rbx
|
||||
mov r8, rbx
|
||||
|
||||
cmp rax, 0
|
||||
jz write_zero_return
|
||||
div_loop:
|
||||
; first division for getting the mod of the number
|
||||
xor rdx, rdx
|
||||
mov rax, r10
|
||||
mov rcx, r9
|
||||
div rcx
|
||||
; if rax is non-zero or we are not in the leading zeroes, write into the buffer
|
||||
cmp rax, 0
|
||||
jne write_ascii_into_buffer
|
||||
cmp r12, 0
|
||||
jz write_ascii_into_buffer
|
||||
; else, skip the write
|
||||
jmp take_remainder_of_number
|
||||
|
||||
write_ascii_into_buffer:
|
||||
; write the ascii number into the buffer
|
||||
add rax, ASCII_NUM
|
||||
mov byte [r8], al
|
||||
inc r8
|
||||
xor r12, r12 ; we are past the leading zeroes, set it to false
|
||||
|
||||
take_remainder_of_number:
|
||||
; if the divisor is one, we are done here
|
||||
cmp r9, 1
|
||||
je return_success
|
||||
|
||||
; now take the remainder of the number for the next loop
|
||||
xor rdx, rdx
|
||||
mov rax, r10
|
||||
mov rcx, r9
|
||||
div rcx
|
||||
mov r10, rdx ; nom = num % div
|
||||
|
||||
; divide the divisor by ten
|
||||
xor rdx, rdx
|
||||
mov rax, r9
|
||||
mov rcx, 10
|
||||
div rcx
|
||||
mov r9, rax
|
||||
|
||||
jmp div_loop
|
||||
|
||||
write_zero_return:
|
||||
mov byte [r8], '0'
|
||||
inc r8
|
||||
return_success:
|
||||
; calculate the length into r8
|
||||
sub r8, r11
|
||||
mov rax, 0 ; return the success code 0
|
||||
mov rbx, r8 ; return the length
|
||||
ret
|
||||
number_too_big:
|
||||
mov rax, 1 ; return error code 1
|
||||
mov rbx, 0 ; we've written nothing
|
||||
ret
|
||||
Loading…
Add table
Add a link
Reference in a new issue