Compare commits
No commits in common. "fa7b4c70b8f669c9c8bb106cb6a23dc8e6de1725" and "63ded22bfd3b4ae50dff6223a877ccc5d7fd3281" have entirely different histories.
fa7b4c70b8
...
63ded22bfd
5
Makefile
5
Makefile
@ -8,11 +8,6 @@ DEBUG_LD_FLAGS := -g
|
|||||||
DEBUG_NASM_FLAGS := -g -F dwarf
|
DEBUG_NASM_FLAGS := -g -F dwarf
|
||||||
|
|
||||||
# check for avx2 support
|
# check for avx2 support
|
||||||
ifeq ($(shell grep -o 'avx2[^ ]*' /proc/cpuinfo | head -n 1),avx512)
|
|
||||||
NASM_FLAGS += -DAVX2
|
|
||||||
endif
|
|
||||||
|
|
||||||
# check for avx512 support
|
|
||||||
ifeq ($(shell grep -o 'avx512[^ ]*' /proc/cpuinfo | head -n 1),avx512)
|
ifeq ($(shell grep -o 'avx512[^ ]*' /proc/cpuinfo | head -n 1),avx512)
|
||||||
NASM_FLAGS += -DAVX512
|
NASM_FLAGS += -DAVX512
|
||||||
endif
|
endif
|
||||||
|
137
src/drawing.asm
137
src/drawing.asm
@ -23,30 +23,17 @@ section .rodata
|
|||||||
|
|
||||||
home_cursor: db ESC_CHAR, "[H", 0
|
home_cursor: db ESC_CHAR, "[H", 0
|
||||||
|
|
||||||
statusbar: db ESC_CHAR, "[32;100m", "Use arrow keys to move cursor, enter to invert cell j/k to change simulation speed, p to simulation", 0
|
statusbar: db ESC_CHAR, "[30;100m", "Use arrow keys to move cursor, enter to invert cell j/k to change simulation speed, p to simulation", 0
|
||||||
START_STOP_pos: equ $-statusbar-17
|
START_STOP_pos: equ $-statusbar-17
|
||||||
|
|
||||||
|
|
||||||
start_str: db "START", 0
|
start_str: db "START", 0
|
||||||
stop_str: db "STOP ", 0
|
stop_str: db "STOP ", 0
|
||||||
|
|
||||||
alive_switch_statement:
|
|
||||||
dq step_simulation.die; 0
|
|
||||||
dq step_simulation.die; 1
|
|
||||||
dq step_simulation.live; 2
|
|
||||||
dq step_simulation.live; 3
|
|
||||||
dq step_simulation.die; 4
|
|
||||||
dq step_simulation.die; 5
|
|
||||||
dq step_simulation.die; 6
|
|
||||||
dq step_simulation.die; 7
|
|
||||||
dq step_simulation.die; 8
|
|
||||||
|
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
extern print_str
|
extern print_str
|
||||||
extern string_copy
|
extern string_copy
|
||||||
extern memory_set
|
extern memory_set
|
||||||
extern memory_copy
|
|
||||||
extern alloc
|
extern alloc
|
||||||
|
|
||||||
global init_gameboard
|
global init_gameboard
|
||||||
@ -112,111 +99,69 @@ print_game_ui:
|
|||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
%macro check_if_hashtag 2
|
%macro check_if_hashtag 1
|
||||||
cmp %1, r8
|
cmp r8, %1
|
||||||
jl .no_count_%2
|
jl +7
|
||||||
cmp %1, r9
|
cmp r9, %1
|
||||||
ja .no_count_%2
|
ja +5
|
||||||
mov r11b, [%1]
|
mov r11b, [%1]
|
||||||
cmp r11b, '#'
|
cmp r11b, '#'
|
||||||
jne .no_count_%2
|
jne +2
|
||||||
inc dl
|
inc dl
|
||||||
.no_count_%2:
|
|
||||||
%endmacro
|
%endmacro
|
||||||
|
|
||||||
global step_simulation:
|
global step_simulation:
|
||||||
step_simulation:
|
step_simultion:
|
||||||
mov rdi, [next_frame_ptr]; destination
|
mov rdi, [next_frame_ptr]; destination
|
||||||
mov rsi, [gameboard_ptr]; source
|
mov rsi, [gameboard_ptr]; source
|
||||||
mov rcx, [gameboard_size]; number of iterations
|
mov rcx, [gameboard_size]; number of iterations
|
||||||
|
|
||||||
mov r8, rsi; store lowest address posible so we are not checking out of bounds
|
mov r8, rsi; store lowest address posible so we are not checking out of bounds
|
||||||
mov r9, rsi
|
mov r9, rsi
|
||||||
add r9, rcx; store higest address posible so we are not checking out of bounds
|
add r9, rcx; store higest address posible so we are not checking out of bounds
|
||||||
|
|
||||||
xor r10, r10
|
mov r10, [term_cols]
|
||||||
mov r10w, [term_cols]
|
|
||||||
;mov r11, [term_rows] this register has been confiscated since i cannot use ah because of error: cannot use high byte register in rex instruction
|
;mov r11, [term_rows] this register has been confiscated since i cannot use ah because of error: cannot use high byte register in rex instruction
|
||||||
|
|
||||||
sub rcx, r10; remove status bar
|
|
||||||
|
|
||||||
xor rax, rax; this shouldn't be needed but just to be sure
|
xor rax, rax; this shouldn't be needed but just to be sure
|
||||||
xor r11, r11
|
xor r11, r11
|
||||||
xor rdx, rdx; we will use dl as # counter
|
xor rdx, rdx; we will use dl as # counter
|
||||||
.for_every_column_on_gameboard:
|
.for_every_column_on_gameboard:
|
||||||
xor dl, dl
|
mov al, [rdi]; NOTE to self if i need extra register i can shift this to ah and free up r11
|
||||||
mov al, [rsi]; NOTE to self if i need extra register i can shift this to ah and free up r11
|
|
||||||
|
|
||||||
|
|
||||||
inc rsi
|
|
||||||
check_if_hashtag rsi, 1; check column to the to the right
|
|
||||||
dec rsi
|
|
||||||
|
|
||||||
dec rsi
|
|
||||||
check_if_hashtag rsi, 2; check the one to the left
|
|
||||||
inc rsi
|
|
||||||
|
|
||||||
add rsi, r10
|
|
||||||
|
|
||||||
check_if_hashtag rsi, 3; check the one to the down
|
|
||||||
|
|
||||||
inc rsi
|
|
||||||
check_if_hashtag rsi, 4; check the one to the down-right
|
|
||||||
dec rsi
|
|
||||||
|
|
||||||
dec rsi
|
|
||||||
check_if_hashtag rsi, 5; check the one to the down-left
|
|
||||||
inc rsi
|
|
||||||
|
|
||||||
sub rsi, r10
|
|
||||||
|
|
||||||
|
|
||||||
sub rsi, r10
|
|
||||||
check_if_hashtag rsi, 6; check the one to the up
|
|
||||||
|
|
||||||
inc rsi
|
|
||||||
check_if_hashtag rsi, 7; check the one to the up-right
|
|
||||||
dec rsi
|
|
||||||
|
|
||||||
dec rsi
|
|
||||||
check_if_hashtag rsi, 8; check the one to the up-left
|
|
||||||
inc rsi
|
|
||||||
|
|
||||||
add rsi, r10
|
|
||||||
|
|
||||||
cmp al, '#'
|
|
||||||
jne .dead_cell
|
|
||||||
|
|
||||||
jmp [alive_switch_statement+(rdx*8)]
|
|
||||||
|
|
||||||
.die:
|
|
||||||
mov byte [rdi], 0x20; SPACE
|
|
||||||
jmp .end_check
|
|
||||||
|
|
||||||
.live:
|
|
||||||
mov byte [rdi], '#'
|
|
||||||
jmp .end_check
|
|
||||||
|
|
||||||
.dead_cell:
|
|
||||||
cmp dl, 3
|
|
||||||
jne .fill_space_there
|
|
||||||
mov byte [rdi], '#'
|
|
||||||
jmp .end_check
|
|
||||||
.fill_space_there:
|
|
||||||
mov byte [rdi], 0x20; SPACE
|
|
||||||
|
|
||||||
.end_check:
|
|
||||||
dec rcx
|
|
||||||
inc rdi
|
inc rdi
|
||||||
inc rsi
|
check_if_hashtag rdi
|
||||||
test rcx, rcx
|
dec rdi
|
||||||
jnz .for_every_column_on_gameboard
|
|
||||||
|
|
||||||
mov rsi, [next_frame_ptr]; source
|
check_if_hashtag rdi-1
|
||||||
mov rdi, [gameboard_ptr]; destination
|
|
||||||
mov rdx, [gameboard_size]; number of iterations
|
|
||||||
sub rdx, r10; remove statusbar
|
|
||||||
|
|
||||||
call memory_copy
|
|
||||||
|
add rdi, r10
|
||||||
|
|
||||||
|
check_if_hashtag rdi
|
||||||
|
|
||||||
|
inc rdi
|
||||||
|
check_if_hashtag rdi
|
||||||
|
dec rdi
|
||||||
|
|
||||||
|
check_if_hashtag rdi-1
|
||||||
|
|
||||||
|
sub rdi, r10
|
||||||
|
|
||||||
|
|
||||||
|
sub rdi, r10
|
||||||
|
check_if_hashtag rdi
|
||||||
|
|
||||||
|
inc rdi
|
||||||
|
check_if_hashtag rdi
|
||||||
|
dec rdi
|
||||||
|
|
||||||
|
check_if_hashtag rdi-1
|
||||||
|
|
||||||
|
add rdi, r10
|
||||||
|
|
||||||
|
|
||||||
|
; TODO create jump table
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
193
src/input.asm
193
src/input.asm
@ -1,8 +1,8 @@
|
|||||||
%include "symbols.asm"
|
%include "symbols.asm"
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
alignb 16
|
cursor_rows: RESW 1; TODO DONT FORGET TO INICIALIZE
|
||||||
termios: RESZ 1; 60 bytes is needed i use 64 for alligment and it is easier to work with
|
cursor_cols: RESW 1
|
||||||
|
|
||||||
extern multipurpuse_buf
|
extern multipurpuse_buf
|
||||||
|
|
||||||
@ -12,16 +12,13 @@ section .bss
|
|||||||
extern gameboard_ptr
|
extern gameboard_ptr
|
||||||
|
|
||||||
extern simulation_running
|
extern simulation_running
|
||||||
section .data
|
|
||||||
cursor_rows: dw 1
|
|
||||||
cursor_cols: dw 1
|
|
||||||
section .rodata
|
section .rodata
|
||||||
|
|
||||||
cursor_up: db ESC_CHAR, "[1A", 0
|
cursor_up: db ESC_CHAR, "[1A", 0
|
||||||
cursor_down: db ESC_CHAR, "[1B", 0
|
cursor_down: db ESC_CHAR, "[1B", 0
|
||||||
cursor_right: db ESC_CHAR, "[1C", 0
|
cursor_right: db ESC_CHAR, "[1C", 0
|
||||||
cursor_left: db ESC_CHAR, "[1D", 0
|
cursor_left: db ESC_CHAR, "[1D", 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
arrow_switch_statement:
|
arrow_switch_statement:
|
||||||
@ -33,144 +30,73 @@ section .rodata
|
|||||||
section .text
|
section .text
|
||||||
|
|
||||||
extern print_str
|
extern print_str
|
||||||
extern step_simulation
|
|
||||||
extern unsigned_int_to_ascii
|
|
||||||
extern print_game_ui
|
|
||||||
|
|
||||||
global handle_user_input
|
global handle_user_input
|
||||||
handle_user_input:; main loop of the program
|
handle_user_input:; main loop of the program
|
||||||
push r12
|
|
||||||
|
|
||||||
lea r12, [multipurpuse_buf]
|
|
||||||
|
|
||||||
.main_loop:
|
.main_loop:
|
||||||
|
|
||||||
; put the cursor where it should be
|
|
||||||
mov rdi, r12; multipurpuse_buf pointer is in r12
|
|
||||||
mov word [rdi], 0x5B1B; will store ESC_CHAR, '[' they have to be in reverse order here due to little endian
|
|
||||||
add rdi, 2
|
|
||||||
push rdi
|
|
||||||
xor rsi, rsi
|
|
||||||
mov si, [cursor_rows]
|
|
||||||
call unsigned_int_to_ascii
|
|
||||||
pop rdi
|
|
||||||
add rdi, rax; add lenght of string to pointer
|
|
||||||
mov byte [rdi], ';'
|
|
||||||
inc rdi
|
|
||||||
push rdi
|
|
||||||
mov si, [cursor_cols]
|
|
||||||
call unsigned_int_to_ascii
|
|
||||||
pop rdi
|
|
||||||
add rdi, rax
|
|
||||||
mov byte [rdi], 'H'
|
|
||||||
inc rdi
|
|
||||||
mov byte [rdi], 0; null terminate
|
|
||||||
|
|
||||||
mov rdi, r12; multipurpuse_buf pointer is in r12
|
|
||||||
call print_str
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
xor rax, rax
|
xor rax, rax
|
||||||
mov qword [r12], rax; zeroout the buffer
|
mov qword [multipurpuse_buf], rax; zeroout the buffer
|
||||||
|
|
||||||
mov rax, SYS_POLL
|
mov rax, SYS_POLL
|
||||||
mov dword [r12], STDIN; create pollfd struct
|
mov rdi, STDIN
|
||||||
mov word [r12+4], POLLIN
|
|
||||||
mov rdi, r12
|
|
||||||
mov rsi, 1; only one file descriptor is provided
|
mov rsi, 1; only one file descriptor is provided
|
||||||
mov rdx, 500; no timeout. maybe use this for final sleep but run if user inputs something TODO
|
mov rdx, 0; no timeout. maybe use this for final sleep but run if user inputs something TODO
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
test rax, rax; SYS_POLL returns 0 when no change happens within timeout
|
test rax, rax; SYS_POLL returns 0 when no change happens within timeout
|
||||||
jz .no_input
|
jz .no_input
|
||||||
|
|
||||||
xor rax, rax
|
|
||||||
mov qword [r12], rax; zeroout the buffer
|
|
||||||
|
|
||||||
mov rax, SYS_READ
|
mov rax, SYS_READ
|
||||||
mov rdi, STDIN
|
mov rdi, STDIN
|
||||||
lea rsi, [r12]
|
lea rsi, [multipurpuse_buf]
|
||||||
mov rdx, 8; size of multipurpuse buffer
|
mov rdx, 8; size of multipurpuse buffer
|
||||||
syscall; read user input
|
syscall; read user input
|
||||||
|
|
||||||
cmp rax, EAGAIN
|
mov rax, [multipurpuse_buf]
|
||||||
je .no_input
|
shr rax, 5; we need only 3 bytes for this inpus sceame
|
||||||
|
|
||||||
mov rax, [r12]
|
cmp eax, 0x001B5B44; check if input is more than left arrow
|
||||||
|
ja .handle_single_byte_chars
|
||||||
cmp eax, 0x00415B1B; check if input is more than left arrow
|
|
||||||
jl .handle_single_byte_chars
|
|
||||||
|
|
||||||
bswap eax
|
|
||||||
|
|
||||||
sub eax, 0x1B5B4100
|
|
||||||
shr eax, 8
|
|
||||||
cmp al, 3
|
|
||||||
ja .no_input
|
|
||||||
|
|
||||||
mov r9w, [term_rows]
|
|
||||||
dec r9w
|
|
||||||
mov r10w, [term_cols]
|
|
||||||
|
|
||||||
|
sub eax, 0x1B5B41
|
||||||
jmp [arrow_switch_statement+(rax*8)]; lets hope this works
|
jmp [arrow_switch_statement+(rax*8)]; lets hope this works
|
||||||
|
|
||||||
.arrow_up:
|
.arrow_up:
|
||||||
dec word [cursor_rows]
|
dec word [cursor_rows]
|
||||||
jnz .move_cursor_up
|
|
||||||
inc word [cursor_rows]
|
|
||||||
jmp .no_input
|
|
||||||
.move_cursor_up:
|
|
||||||
lea rdi, [cursor_up]
|
lea rdi, [cursor_up]
|
||||||
call print_str
|
call print_str
|
||||||
jmp .no_input
|
jmp .no_input
|
||||||
|
|
||||||
.arrow_down:
|
.arrow_down:
|
||||||
mov r8w, [cursor_rows]
|
inc word [cursor_rows]
|
||||||
inc r8w
|
|
||||||
cmp word r8w, r9w
|
|
||||||
ja .no_input
|
|
||||||
mov word [cursor_rows], r8w
|
|
||||||
lea rdi, [cursor_down]
|
lea rdi, [cursor_down]
|
||||||
call print_str
|
call print_str
|
||||||
jmp .no_input
|
jmp .no_input
|
||||||
|
|
||||||
.arrow_right:
|
.arrow_right:
|
||||||
mov r8w, [cursor_cols]
|
inc word [cursor_cols]
|
||||||
inc r8w
|
|
||||||
cmp word r8w, r10w
|
|
||||||
ja .no_input
|
|
||||||
mov word [cursor_cols], r8w
|
|
||||||
lea rdi, [cursor_right]
|
lea rdi, [cursor_right]
|
||||||
call print_str
|
call print_str
|
||||||
jmp .no_input
|
jmp .no_input
|
||||||
|
|
||||||
.arrow_left:
|
.arrow_left:
|
||||||
dec word [cursor_cols]
|
dec word [cursor_cols]
|
||||||
jnz .move_cursor_left
|
|
||||||
inc word [cursor_cols]
|
|
||||||
jmp .no_input
|
|
||||||
.move_cursor_left:
|
|
||||||
lea rdi, [cursor_left]
|
lea rdi, [cursor_left]
|
||||||
call print_str
|
call print_str
|
||||||
jmp .no_input
|
jmp .no_input
|
||||||
|
|
||||||
.handle_single_byte_chars:
|
.handle_single_byte_chars:
|
||||||
|
|
||||||
|
shr eax, 2; get the char to al
|
||||||
|
|
||||||
cmp al, 0xa; NEWLINE (enter key)
|
cmp al, 0xa; NEWLINE (enter key)
|
||||||
jne .check_p
|
jne .check_p
|
||||||
|
|
||||||
xor rax, rax; zeroout rax
|
xor rax, rax; zeroout rax
|
||||||
mov ax, [cursor_rows]
|
mov ax, [cursor_rows]
|
||||||
dec ax
|
mul dword [term_cols]
|
||||||
mul word [term_cols]
|
add rax, [cursor_cols]
|
||||||
mov cx, [cursor_cols]
|
|
||||||
dec cx
|
|
||||||
add ax, cx
|
|
||||||
|
|
||||||
mov rdi, [gameboard_ptr]
|
lea rdi, [gameboard_ptr+rax]
|
||||||
add rdi, rax
|
|
||||||
mov cl, [rdi]
|
mov cl, [rdi]
|
||||||
cmp cl, '#'
|
cmp cl, '#'
|
||||||
je .hashtag_present
|
je .hashtag_present
|
||||||
@ -201,92 +127,15 @@ handle_user_input:; main loop of the program
|
|||||||
|
|
||||||
.check_k:
|
.check_k:
|
||||||
cmp al, 'k'
|
cmp al, 'k'
|
||||||
jne .check_q
|
jne .no_input
|
||||||
|
|
||||||
; TODO implement simulation speed
|
; TODO implement simulation speed
|
||||||
|
|
||||||
.check_q:
|
|
||||||
cmp al, 'q'
|
|
||||||
jne .no_input
|
|
||||||
pop r12
|
|
||||||
ret; exit if q pressed
|
|
||||||
|
|
||||||
.no_input:
|
.no_input:
|
||||||
|
|
||||||
mov al, [simulation_running]
|
|
||||||
test al, al
|
|
||||||
jz .dont_step
|
|
||||||
call step_simulation
|
|
||||||
.dont_step:
|
|
||||||
call print_game_ui
|
|
||||||
jmp .main_loop
|
jmp .main_loop
|
||||||
|
|
||||||
pop r12
|
|
||||||
ret
|
|
||||||
|
|
||||||
|
|
||||||
global disable_canonical_mode_and_echo
|
|
||||||
disable_canonical_mode_and_echo:
|
|
||||||
|
|
||||||
mov rax, SYS_IOCTL
|
|
||||||
mov rdi, STDIN
|
|
||||||
mov rsi, TCGETS
|
|
||||||
lea rdx, [termios]
|
|
||||||
syscall
|
|
||||||
|
|
||||||
; save original termios struct
|
|
||||||
%ifdef AVX2
|
|
||||||
%ifdef AVX512
|
|
||||||
vmovdqa64 zmm0, [termios]
|
|
||||||
%else
|
|
||||||
vmovdqa ymm0, [termios]
|
|
||||||
vmovdqa ymm1, [termios+32]
|
|
||||||
%endif
|
|
||||||
%else
|
|
||||||
vmovdqa xmm0, [termios]
|
|
||||||
vmovdqa xmm1, [termios+16]
|
|
||||||
vmovdqa xmm2, [termios+32]
|
|
||||||
vmovdqa xmm3, [termios+64]
|
|
||||||
%endif
|
|
||||||
|
|
||||||
|
|
||||||
mov eax, [termios+12]; get c_lflag
|
|
||||||
and eax, NOT_ECHO; disable ECHO
|
|
||||||
and eax, NOT_ICANON; disable ICANON
|
|
||||||
mov [termios+12], eax
|
|
||||||
|
|
||||||
mov rax, SYS_IOCTL
|
|
||||||
mov rdi, STDIN
|
|
||||||
mov rsi, TCSETS
|
|
||||||
lea rdx, [termios]
|
|
||||||
syscall
|
|
||||||
|
|
||||||
|
|
||||||
; load original termios struct
|
|
||||||
%ifdef AVX2
|
|
||||||
%ifdef AVX512
|
|
||||||
vmovdqa64 [termios], zmm0
|
|
||||||
%else
|
|
||||||
vmovdqa [termios], ymm0
|
|
||||||
vmovdqa [termios+32], ymm1
|
|
||||||
%endif
|
|
||||||
%else
|
|
||||||
vmovdqa [termios], xmm0
|
|
||||||
vmovdqa [termios+16], xmm1
|
|
||||||
vmovdqa [termios+32], xmm2
|
|
||||||
vmovdqa [termios+64], xmm3
|
|
||||||
%endif
|
|
||||||
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
global reset_terminal
|
|
||||||
reset_terminal:
|
|
||||||
mov rax, SYS_IOCTL
|
|
||||||
mov rdi, STDIN
|
|
||||||
mov rsi, TCSETS
|
|
||||||
lea rdx, [termios]
|
|
||||||
syscall
|
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,11 +33,6 @@ extern alloc
|
|||||||
extern init_gameboard
|
extern init_gameboard
|
||||||
extern print_game_ui
|
extern print_game_ui
|
||||||
|
|
||||||
extern handle_user_input
|
|
||||||
|
|
||||||
extern disable_canonical_mode_and_echo
|
|
||||||
extern reset_terminal
|
|
||||||
|
|
||||||
global _start
|
global _start
|
||||||
_start:
|
_start:
|
||||||
; get terminal dimensions
|
; get terminal dimensions
|
||||||
@ -87,11 +82,7 @@ _start:
|
|||||||
|
|
||||||
call print_game_ui
|
call print_game_ui
|
||||||
|
|
||||||
call disable_canonical_mode_and_echo
|
|
||||||
|
|
||||||
call handle_user_input
|
|
||||||
|
|
||||||
call reset_terminal
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
52
src/str.asm
52
src/str.asm
@ -24,7 +24,7 @@ print_str: ; takes pointer to string in rdi and retuns in rax
|
|||||||
ret
|
ret
|
||||||
|
|
||||||
global unsigned_int_to_ascii
|
global unsigned_int_to_ascii
|
||||||
unsigned_int_to_ascii: ; takes pointer to array in rdi and value stored in rsi DOES NOT BOUNDS CHECK return len of string in rax
|
unsigned_int_to_ascii: ; takes pointer to array in rdi and value stored in rsi DOES NOT BOUNDS CHECK
|
||||||
xor r11, r11
|
xor r11, r11
|
||||||
mov rcx, 10
|
mov rcx, 10
|
||||||
mov rax, rsi
|
mov rax, rsi
|
||||||
@ -154,16 +154,52 @@ memory_copy:; takes destination in rdi, source in rsi and lenght in rdx
|
|||||||
|
|
||||||
mov r9, rdi
|
mov r9, rdi
|
||||||
|
|
||||||
mov rcx, rdx
|
cmp rdx, 16
|
||||||
shr rcx, 3; calculate how many 8 byte chunks we need
|
jnl .write_16_or_more_bytes
|
||||||
and rdx, 0x7; calculate the reminder
|
mov rcx, rdx
|
||||||
|
jmp .write_less_than_16_bytes
|
||||||
|
.write_16_or_more_bytes:
|
||||||
|
mov rax, rdi; move destination to rax
|
||||||
|
and rax, 0xF; offset is stored in rax
|
||||||
|
|
||||||
rep movsq; move as many 8 byte chunks as posible
|
|
||||||
|
test al, al; check if resault is 0
|
||||||
|
jz .addr_is_16_Byte_alligned
|
||||||
|
|
||||||
|
|
||||||
mov rcx, rdx
|
mov cl, 16
|
||||||
|
sub cl, al; now offset to first higher 16 byte alligned address is stored in r8
|
||||||
|
movzx rcx, cl; remove ani posible garbage
|
||||||
|
|
||||||
|
|
||||||
rep movsb; move the rest
|
.write_less_than_16_bytes:
|
||||||
|
sub rdx, rcx; we will write these bytes now
|
||||||
|
|
||||||
|
rep movsb
|
||||||
|
|
||||||
|
.addr_is_16_Byte_alligned:
|
||||||
|
mov r10, rdx
|
||||||
|
shr r10, 4; set it to how many 128bit(16Byte) chunk we need
|
||||||
|
test r10, r10; check if we need to write aditional 16 bytes at all
|
||||||
|
jz .function_exit
|
||||||
|
|
||||||
|
.move_16_bytes:
|
||||||
|
movdqa xmm8, [rsi]
|
||||||
|
movdqa [rdi], xmm8
|
||||||
|
add rdi, 16
|
||||||
|
add rsi, 16
|
||||||
|
sub rdx, 16
|
||||||
|
|
||||||
mov rax, r9; return pointer to memory area same as memcpy in libc
|
cmp rdx, 16; test if rdx is less than 16
|
||||||
|
jge .move_16_bytes
|
||||||
|
|
||||||
|
.function_exit:
|
||||||
|
|
||||||
|
test rdx, rdx; test if rdx is 0
|
||||||
|
jz .true_function_exit
|
||||||
|
movzx rcx, dl
|
||||||
|
jmp .write_less_than_16_bytes
|
||||||
|
|
||||||
|
.true_function_exit:
|
||||||
|
mov rax, r9; return pointer to memory area same as memset in libc
|
||||||
ret
|
ret
|
||||||
|
@ -10,16 +10,9 @@ STDIN equ 0
|
|||||||
STDOUT equ 1
|
STDOUT equ 1
|
||||||
|
|
||||||
TIOCGWINSZ equ 0x5413
|
TIOCGWINSZ equ 0x5413
|
||||||
TCGETS equ 0x5401
|
POLLIN equ 1
|
||||||
TCSETS equ 0x5402
|
|
||||||
F_SETFL equ 4
|
F_SETFL equ 4
|
||||||
O_NONBLOCK equ 2048
|
O_NONBLOCK equ 2048
|
||||||
POLLIN equ 0x0100; compensate for litle endian
|
|
||||||
|
|
||||||
NOT_ECHO equ -9
|
|
||||||
NOT_ICANON equ -3
|
|
||||||
|
|
||||||
EAGAIN equ -11
|
|
||||||
|
|
||||||
ASCII_ZERO equ 48
|
ASCII_ZERO equ 48
|
||||||
ESC_CHAR equ 27
|
ESC_CHAR equ 27
|
||||||
|
Loading…
x
Reference in New Issue
Block a user