Compare commits
38 Commits
4c3ffab97b
..
v1.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 719bc17fcd | |||
| 5c91ace69b | |||
| 872c842e7c | |||
| a6a7debf2e | |||
| 57987228b0 | |||
| 83d3f3ac5a | |||
| 45c6d0eb83 | |||
| 670a6a2602 | |||
| e70b9ac765 | |||
| 6112537e9b | |||
| 3e59f36d4e | |||
| f26553e7c7 | |||
| db00e98b4c | |||
| b449c66a66 | |||
| 7dc5237c3e | |||
| 7fd699ea38 | |||
| b5c539a3a2 | |||
| ce343ff9db | |||
| d6ee106682 | |||
| 5b56f6bcb6 | |||
| 4a8db75bef | |||
| fa7b4c70b8 | |||
| a46f907ff6 | |||
| 63ded22bfd | |||
| 00cc777183 | |||
| b94ebe30c8 | |||
| c5e404f1dd | |||
| 564a6b88c1 | |||
| d6613ac341 | |||
| 2b8236ee91 | |||
| c0bd3fcbc3 | |||
| 76093db3c9 | |||
| 9092d1276a | |||
| 35a6894d9f | |||
| a2a5b4c972 | |||
| 51ffd98872 | |||
| c1a55fa3ff | |||
| aa86683b35 |
@@ -0,0 +1,17 @@
|
|||||||
|
name: build_test
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: arch
|
||||||
|
steps:
|
||||||
|
- name: fix package cache
|
||||||
|
run: rm -fr /var/cache/pacman/pkg/* && pacman -Syy archlinux-keyring --needed --noconfirm && pacman-key --init && pacman-key --populate archlinux
|
||||||
|
- name: get dependencies
|
||||||
|
run: pacman -Sy nodejs make nasm binutils --needed --noconfirm
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: make -j$(nproc)
|
||||||
@@ -1 +1,3 @@
|
|||||||
|
.asm-lsp.toml
|
||||||
build
|
build
|
||||||
|
src/*.o
|
||||||
|
|||||||
@@ -1,31 +1,49 @@
|
|||||||
NASM = nasm
|
NASM = nasm
|
||||||
LD = ld
|
LD = ld
|
||||||
|
|
||||||
NASM_FLAGS := -felf64
|
NASM_FLAGS := -felf64 -Isrc -Ox -Ov -w+all -w-reloc-abs-dword -w-reloc-rel-dword
|
||||||
LD_FLAGS := --strip-all
|
LD_FLAGS := --strip-all
|
||||||
|
|
||||||
|
DEBUG_LD_FLAGS := -g
|
||||||
|
DEBUG_NASM_FLAGS := -g -F dwarf
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
NASM_FLAGS += -DAVX512
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
SRC_PATH := src
|
SRC_PATH := src
|
||||||
OBJ_PATH := build/obj
|
OBJ_PATH := build/obj
|
||||||
BIN_PATH := build/bin
|
BIN_PATH := build/bin
|
||||||
|
|
||||||
|
BIN_NAME := asm-game-of-life
|
||||||
|
|
||||||
SRC_FILES := $(wildcard $(SRC_PATH)/*.asm)
|
SRC_FILES := $(wildcard $(SRC_PATH)/*.asm)
|
||||||
OBJ_FILES := $(patsubst $(SRC_PATH)/%.asm,$(OBJ_PATH)/%.o,$(SRC_FILES))
|
OBJ_FILES := $(patsubst $(SRC_PATH)/%.asm,$(OBJ_PATH)/%.o,$(SRC_FILES))
|
||||||
|
|
||||||
all: make-build-dir $(BIN_PATH)/asm-game-of-life
|
all: $(BIN_PATH)/$(BIN_NAME) | make-build-dir
|
||||||
|
|
||||||
|
debug: NASM_FLAGS += $(DEBUG_NASM_FLAGS)
|
||||||
|
debug: LD_FLAGS = $(DEBUG_LD_FLAGS)
|
||||||
|
debug: $(BIN_PATH)/$(BIN_NAME) | make-build-dir
|
||||||
|
|
||||||
make-build-dir:
|
make-build-dir:
|
||||||
mkdir -p $(OBJ_PATH)
|
mkdir -p $(OBJ_PATH)
|
||||||
mkdir -p $(BIN_PATH)
|
mkdir -p $(BIN_PATH)
|
||||||
|
|
||||||
|
|
||||||
$(BIN_PATH)/asm-game-of-life: $(OBJ_FILES)
|
$(BIN_PATH)/$(BIN_NAME): $(OBJ_FILES) | make-build-dir
|
||||||
$(LD) $(LD_FLAGS) $^ -o $@
|
$(LD) $(LD_FLAGS) $^ -o $@
|
||||||
|
|
||||||
|
|
||||||
$(OBJ_PATH)/%.o: $(SRC_PATH)/%.asm
|
$(OBJ_PATH)/%.o: $(SRC_PATH)/%.asm | make-build-dir
|
||||||
$(NASM) $(NASM_FLAGS) $< -o $@
|
$(NASM) $(NASM_FLAGS) $< -o $@
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -fr build
|
rm -fr build
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<img src="https://git.pupes.org/repo-avatars/e4ede9d30f070c9e191eace5a88dcaa40434b9cadf60204122fab5a83aec9a9f" alt="logo of ParaDocs" width="196"></img>
|
||||||
|
[](https://git.pupes.org/PoliEcho/asm-game-of-life/actions?workflow=build_test.yaml)
|
||||||
|
# AMD64 Assembly Game of life
|
||||||
|
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
> AMD64 Linux Kernel
|
||||||
|
### Build only
|
||||||
|
> nasm
|
||||||
|
> ld
|
||||||
|
> make
|
||||||
|
|
||||||
|
## Download
|
||||||
|
#### TODO: add releases link
|
||||||
|
|
||||||
|
## Build
|
||||||
|
```shell
|
||||||
|
make
|
||||||
|
```
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%include "symbols.asm"
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
brk_pointer: RESQ 1
|
||||||
|
section .text
|
||||||
|
|
||||||
|
global init_alloc
|
||||||
|
init_alloc:; initialize allocator, optionaly return brk pointer in rax
|
||||||
|
mov rax, SYS_BRK
|
||||||
|
xor rdi, rdi
|
||||||
|
syscall
|
||||||
|
mov [brk_pointer], rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
global alloc
|
||||||
|
alloc:; Takes lenght of data in rdi and returns pointer in rax
|
||||||
|
mov rax, SYS_BRK
|
||||||
|
mov qword rcx, [brk_pointer]
|
||||||
|
push rcx
|
||||||
|
add rdi, rcx; calculate new BRK address
|
||||||
|
syscall
|
||||||
|
mov [brk_pointer], rax
|
||||||
|
pop rax
|
||||||
|
ret
|
||||||
|
|
||||||
+256
@@ -0,0 +1,256 @@
|
|||||||
|
%include "symbols.asm"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
extern gameboard_ptr
|
||||||
|
|
||||||
|
extern term_rows
|
||||||
|
extern term_cols
|
||||||
|
|
||||||
|
extern gameboard_size
|
||||||
|
|
||||||
|
global simulation_running
|
||||||
|
simulation_running: RESB 1
|
||||||
|
|
||||||
|
next_frame_ptr: RESQ 1
|
||||||
|
section .data
|
||||||
|
extern simulation_speed
|
||||||
|
|
||||||
|
section .rodata
|
||||||
|
clear: db ESC_CHAR, "[2J", 0
|
||||||
|
global reset
|
||||||
|
reset: db ESC_CHAR, "[0m", 0
|
||||||
|
resetLen: equ $-reset-1
|
||||||
|
global resetLen
|
||||||
|
|
||||||
|
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. Frame Delay multiplier:", 0
|
||||||
|
statusbarLen: equ $-statusbar
|
||||||
|
START_STOP_pos: equ statusbarLen-42
|
||||||
|
|
||||||
|
|
||||||
|
start_str: db "START", 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
|
||||||
|
extern print_str
|
||||||
|
extern string_copy
|
||||||
|
extern memory_set
|
||||||
|
extern memory_copy
|
||||||
|
extern alloc
|
||||||
|
extern unsigned_int_to_ascii
|
||||||
|
|
||||||
|
global init_gameboard
|
||||||
|
init_gameboard:
|
||||||
|
xor rax, rax
|
||||||
|
xor rcx, rcx
|
||||||
|
|
||||||
|
|
||||||
|
mov rdi, [gameboard_ptr]
|
||||||
|
push rdi
|
||||||
|
mov rsi, 0x20; set rsi to SPACE character
|
||||||
|
mov rdx, [gameboard_size]
|
||||||
|
push rdx
|
||||||
|
add rdx, ESC_chars_compensation_Len; I dont know how this work but it works so i wont touch it
|
||||||
|
call memory_set
|
||||||
|
|
||||||
|
|
||||||
|
pop rdx
|
||||||
|
pop rdi
|
||||||
|
add rdi, rdx; get pointer to last char on screen
|
||||||
|
push rdx
|
||||||
|
push rdi
|
||||||
|
add rdi, ESC_chars_compensation_Len
|
||||||
|
lea rsi, [reset]
|
||||||
|
|
||||||
|
call string_copy
|
||||||
|
pop rdi
|
||||||
|
xor rax, rax
|
||||||
|
mov ax, [term_cols]
|
||||||
|
sub rdi, rax
|
||||||
|
lea rsi, [statusbar]
|
||||||
|
call string_copy
|
||||||
|
|
||||||
|
pop rdi
|
||||||
|
call alloc
|
||||||
|
mov [next_frame_ptr], rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
global print_game_ui
|
||||||
|
print_game_ui:
|
||||||
|
lea rdi, [home_cursor]
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
mov qword rdi, [gameboard_ptr]
|
||||||
|
push rdi
|
||||||
|
add rdi, [gameboard_size]
|
||||||
|
sub di, [term_cols]
|
||||||
|
push rdi
|
||||||
|
add rdi, START_STOP_pos
|
||||||
|
|
||||||
|
mov cl, [simulation_running]
|
||||||
|
test cl,cl; test if simulation is running
|
||||||
|
jz .simulation_not_running
|
||||||
|
lea rsi, [stop_str]
|
||||||
|
jmp .end_simulation_running_check
|
||||||
|
.simulation_not_running:
|
||||||
|
lea rsi, [start_str]
|
||||||
|
.end_simulation_running_check:
|
||||||
|
call string_copy
|
||||||
|
|
||||||
|
pop rdi
|
||||||
|
add rdi, statusbarLen
|
||||||
|
|
||||||
|
movss xmm0, [simulation_speed]
|
||||||
|
|
||||||
|
cvttss2si rsi, xmm0
|
||||||
|
push rsi
|
||||||
|
push rdi
|
||||||
|
call unsigned_int_to_ascii
|
||||||
|
pop rdi
|
||||||
|
add rdi, rax
|
||||||
|
|
||||||
|
mov byte [rdi], '.'
|
||||||
|
inc rdi
|
||||||
|
|
||||||
|
pop rax
|
||||||
|
cvtsi2ss xmm1, rax
|
||||||
|
|
||||||
|
subss xmm0, xmm1; get only value after decimal point
|
||||||
|
mov rax, 10
|
||||||
|
cvtsi2ss xmm1, rax
|
||||||
|
|
||||||
|
mulss xmm0, xmm1
|
||||||
|
cvttss2si rsi, xmm0; get first decimal point as int
|
||||||
|
|
||||||
|
call unsigned_int_to_ascii; rdi already set
|
||||||
|
|
||||||
|
|
||||||
|
pop rdi
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
%macro check_if_hashtag 2
|
||||||
|
cmp %1, r8
|
||||||
|
jl .no_count_%2
|
||||||
|
cmp %1, r9
|
||||||
|
ja .no_count_%2
|
||||||
|
mov r11b, [%1]
|
||||||
|
cmp r11b, '#'
|
||||||
|
jne .no_count_%2
|
||||||
|
inc dl
|
||||||
|
.no_count_%2:
|
||||||
|
%endmacro
|
||||||
|
|
||||||
|
global step_simulation:
|
||||||
|
step_simulation:
|
||||||
|
mov rdi, [next_frame_ptr]; destination
|
||||||
|
mov rsi, [gameboard_ptr]; source
|
||||||
|
mov rcx, [gameboard_size]; number of iterations
|
||||||
|
|
||||||
|
mov r8, rsi; store lowest address posible so we are not checking out of bounds
|
||||||
|
mov r9, rsi
|
||||||
|
add r9, rcx; store higest address posible so we are not checking out of bounds
|
||||||
|
|
||||||
|
xor r10, r10
|
||||||
|
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
|
||||||
|
|
||||||
|
sub rcx, r10; remove status bar
|
||||||
|
|
||||||
|
xor rax, rax; this shouldn't be needed but just to be sure
|
||||||
|
xor r11, r11
|
||||||
|
xor rdx, rdx; we will use dl as # counter
|
||||||
|
.for_every_column_on_gameboard:
|
||||||
|
xor dl, dl
|
||||||
|
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 rsi
|
||||||
|
test rcx, rcx
|
||||||
|
jnz .for_every_column_on_gameboard
|
||||||
|
|
||||||
|
mov rsi, [next_frame_ptr]; source
|
||||||
|
mov rdi, [gameboard_ptr]; destination
|
||||||
|
mov rdx, [gameboard_size]; number of iterations
|
||||||
|
sub rdx, r10; remove statusbar
|
||||||
|
|
||||||
|
call memory_copy
|
||||||
|
|
||||||
|
ret
|
||||||
+382
@@ -0,0 +1,382 @@
|
|||||||
|
%include "symbols.asm"
|
||||||
|
|
||||||
|
section .bss
|
||||||
|
alignb 16
|
||||||
|
termios: RESZ 1; 60 bytes is needed i use 64 for alligment and it is easier to work with
|
||||||
|
|
||||||
|
extern multipurpuse_buf
|
||||||
|
|
||||||
|
extern term_rows
|
||||||
|
extern term_cols
|
||||||
|
|
||||||
|
extern gameboard_ptr
|
||||||
|
|
||||||
|
extern simulation_running
|
||||||
|
section .data
|
||||||
|
cursor_rows: dw 1
|
||||||
|
cursor_cols: dw 1
|
||||||
|
|
||||||
|
|
||||||
|
global simulation_speed
|
||||||
|
simulation_speed dd 1.0
|
||||||
|
section .rodata
|
||||||
|
extern reset
|
||||||
|
|
||||||
|
cursor_up: db ESC_CHAR, "[1A", 0
|
||||||
|
cursor_down: db ESC_CHAR, "[1B", 0
|
||||||
|
cursor_right: db ESC_CHAR, "[1C", 0
|
||||||
|
cursor_left: db ESC_CHAR, "[1D", 0
|
||||||
|
|
||||||
|
cursor_color: db ESC_CHAR, "[45m", 0
|
||||||
|
|
||||||
|
speed_multiplier dd 50.0
|
||||||
|
|
||||||
|
arrow_switch_statement:
|
||||||
|
dq handle_user_input.arrow_up
|
||||||
|
dq handle_user_input.arrow_down
|
||||||
|
dq handle_user_input.arrow_right
|
||||||
|
dq handle_user_input.arrow_left
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
extern print_str
|
||||||
|
extern step_simulation
|
||||||
|
extern unsigned_int_to_ascii
|
||||||
|
extern print_game_ui
|
||||||
|
extern string_copy
|
||||||
|
|
||||||
|
global handle_user_input
|
||||||
|
handle_user_input:; main loop of the program
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
|
||||||
|
|
||||||
|
lea r12, [multipurpuse_buf]
|
||||||
|
|
||||||
|
.main_loop:
|
||||||
|
xor r13, r13
|
||||||
|
|
||||||
|
; put the cursor where it should be
|
||||||
|
call print_cursor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
mov qword [r12], rax; zeroout the buffer
|
||||||
|
|
||||||
|
mov rax, SYS_POLL
|
||||||
|
mov dword [r12], STDIN; create pollfd struct
|
||||||
|
mov word [r12+4], POLLIN
|
||||||
|
mov rdi, r12
|
||||||
|
mov rsi, 1; only one file descriptor is provided
|
||||||
|
movss xmm0, [speed_multiplier]
|
||||||
|
movss xmm1, [simulation_speed]
|
||||||
|
mulss xmm0, xmm1; callculate sleep lenght
|
||||||
|
cvttss2si rdx, xmm0; truncate and copy to rdx
|
||||||
|
syscall
|
||||||
|
|
||||||
|
test rax, rax; SYS_POLL returns 0 when no change happens within timeout
|
||||||
|
jz .no_input
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
mov qword [r12], rax; zeroout the buffer
|
||||||
|
|
||||||
|
mov rax, SYS_READ
|
||||||
|
mov rdi, STDIN
|
||||||
|
lea rsi, [r12]
|
||||||
|
mov rdx, 8; size of multipurpuse buffer
|
||||||
|
syscall; read user input
|
||||||
|
|
||||||
|
cmp rax, EAGAIN
|
||||||
|
je .no_input
|
||||||
|
|
||||||
|
mov rax, [r12]
|
||||||
|
|
||||||
|
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]
|
||||||
|
|
||||||
|
jmp [arrow_switch_statement+(rax*8)]; lets hope this works
|
||||||
|
|
||||||
|
.arrow_up:
|
||||||
|
dec word [cursor_rows]
|
||||||
|
jnz .move_cursor_up
|
||||||
|
inc word [cursor_rows]
|
||||||
|
jmp .end_input_handling
|
||||||
|
.move_cursor_up:
|
||||||
|
lea rdi, [cursor_up]
|
||||||
|
call print_str
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.arrow_down:
|
||||||
|
mov r8w, [cursor_rows]
|
||||||
|
inc r8w
|
||||||
|
cmp word r8w, r9w
|
||||||
|
ja .end_input_handling
|
||||||
|
mov word [cursor_rows], r8w
|
||||||
|
lea rdi, [cursor_down]
|
||||||
|
call print_str
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.arrow_right:
|
||||||
|
mov r8w, [cursor_cols]
|
||||||
|
inc r8w
|
||||||
|
cmp word r8w, r10w
|
||||||
|
ja .end_input_handling
|
||||||
|
mov word [cursor_cols], r8w
|
||||||
|
lea rdi, [cursor_right]
|
||||||
|
call print_str
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.arrow_left:
|
||||||
|
dec word [cursor_cols]
|
||||||
|
jnz .move_cursor_left
|
||||||
|
inc word [cursor_cols]
|
||||||
|
jmp .end_input_handling
|
||||||
|
.move_cursor_left:
|
||||||
|
lea rdi, [cursor_left]
|
||||||
|
call print_str
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.handle_single_byte_chars:
|
||||||
|
|
||||||
|
|
||||||
|
cmp al, 0xa; NEWLINE (enter key)
|
||||||
|
jne .check_p
|
||||||
|
|
||||||
|
xor rax, rax; zeroout rax
|
||||||
|
mov ax, [cursor_rows]
|
||||||
|
dec ax
|
||||||
|
mul word [term_cols]
|
||||||
|
mov cx, [cursor_cols]
|
||||||
|
dec cx
|
||||||
|
add ax, cx
|
||||||
|
|
||||||
|
mov rdi, [gameboard_ptr]
|
||||||
|
add rdi, rax
|
||||||
|
mov cl, [rdi]
|
||||||
|
cmp cl, '#'
|
||||||
|
je .hashtag_present
|
||||||
|
|
||||||
|
mov byte [rdi], '#'
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.hashtag_present:
|
||||||
|
|
||||||
|
mov byte [rdi], ' '
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.check_p:
|
||||||
|
cmp al, 'p'
|
||||||
|
jne .check_j
|
||||||
|
|
||||||
|
xor byte [simulation_running], 0x01; switch simulation on or off
|
||||||
|
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.check_j:
|
||||||
|
cmp al, 'j'
|
||||||
|
jne .check_k
|
||||||
|
|
||||||
|
movss xmm0, [simulation_speed]
|
||||||
|
mov eax, 0x3DCCCCCD; 0.1f
|
||||||
|
vmovd xmm1, eax
|
||||||
|
|
||||||
|
addss xmm0, xmm1
|
||||||
|
; wont check for overflows since the user would need be crazy to reach that number
|
||||||
|
movss [simulation_speed], xmm0
|
||||||
|
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.check_k:
|
||||||
|
cmp al, 'k'
|
||||||
|
jne .check_q
|
||||||
|
|
||||||
|
movss xmm0, [simulation_speed]
|
||||||
|
mov eax, 0x3DCCCCCD; 0.1f
|
||||||
|
vmovd xmm1, eax
|
||||||
|
|
||||||
|
subss xmm0, xmm1
|
||||||
|
|
||||||
|
ucomiss xmm0, xmm1; check if number is smaller than 0.1
|
||||||
|
jb .end_input_handling
|
||||||
|
movss [simulation_speed], xmm0
|
||||||
|
|
||||||
|
jmp .end_input_handling
|
||||||
|
|
||||||
|
.check_q:
|
||||||
|
cmp al, 'q'
|
||||||
|
jne .end_input_handling
|
||||||
|
jmp .function_exit
|
||||||
|
ret; exit if q pressed
|
||||||
|
|
||||||
|
.end_input_handling:
|
||||||
|
mov r13b, 1
|
||||||
|
.no_input:
|
||||||
|
|
||||||
|
mov al, [simulation_running]
|
||||||
|
test al, al
|
||||||
|
jz .dont_step
|
||||||
|
call step_simulation
|
||||||
|
mov r13b, 1
|
||||||
|
.dont_step:
|
||||||
|
|
||||||
|
test r13b, r13b
|
||||||
|
jz .main_loop
|
||||||
|
call print_game_ui
|
||||||
|
jmp .main_loop
|
||||||
|
|
||||||
|
.function_exit:
|
||||||
|
pop r13
|
||||||
|
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
|
||||||
|
|
||||||
|
print_cursor:
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
lea r12, [multipurpuse_buf]
|
||||||
|
mov rdi, 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
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
; write there real cursor
|
||||||
|
xor r13, r13
|
||||||
|
mov rdi, r12
|
||||||
|
lea rsi, [cursor_color]
|
||||||
|
call string_copy
|
||||||
|
mov rdi, r12
|
||||||
|
add r13, rax
|
||||||
|
add rdi, r13
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
|
||||||
|
mov ax, [cursor_rows]
|
||||||
|
dec ax
|
||||||
|
mul word [term_cols]; get index of character
|
||||||
|
add ax, [cursor_cols]
|
||||||
|
dec ax
|
||||||
|
|
||||||
|
xor rsi, rsi
|
||||||
|
|
||||||
|
add rax, [gameboard_ptr]
|
||||||
|
mov sil, [rax]; now we got the character in si
|
||||||
|
mov byte [rdi], sil
|
||||||
|
inc rdi
|
||||||
|
inc r13
|
||||||
|
|
||||||
|
lea rsi, [reset]
|
||||||
|
call string_copy
|
||||||
|
mov rdi, r12
|
||||||
|
add r13, rax
|
||||||
|
add rdi, r13
|
||||||
|
|
||||||
|
lea rsi, [cursor_left]
|
||||||
|
call string_copy
|
||||||
|
mov rdi, r12
|
||||||
|
add r13, rax
|
||||||
|
add rdi, r13
|
||||||
|
|
||||||
|
inc rdi
|
||||||
|
mov byte [rdi], 0; null terminate
|
||||||
|
|
||||||
|
mov rdi, r12
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
pop r13
|
||||||
|
pop r12
|
||||||
|
ret
|
||||||
|
|
||||||
+134
-93
@@ -1,115 +1,156 @@
|
|||||||
SYS_WRITE equ 1
|
%include "symbols.asm"
|
||||||
SYS_BRK equ 12
|
|
||||||
SYS_EXIT equ 60
|
|
||||||
|
|
||||||
STDOUT equ 1
|
|
||||||
|
|
||||||
ESC_CHAR equ 27
|
|
||||||
ASCII_ZERO equ 48
|
|
||||||
|
|
||||||
section .bss
|
section .bss
|
||||||
heap_ptr resp 1
|
global multipurpuse_buf
|
||||||
|
multipurpuse_buf: RESB 16
|
||||||
|
|
||||||
section .data
|
global term_rows
|
||||||
hello: db ESC_CHAR, "[10;15Hhello suckers! :)", 10, 0
|
term_rows: RESW 1
|
||||||
test: db ESC_CHAR, "[20;25Hmore txt here", 10, 0
|
global term_cols
|
||||||
clear: db ESC_CHAR, "[2J", 0
|
term_cols: RESW 1
|
||||||
|
|
||||||
|
global gameboard_ptr
|
||||||
|
gameboard_ptr: RESQ 1
|
||||||
|
|
||||||
|
global gameboard_size
|
||||||
|
gameboard_size: RESQ 1
|
||||||
|
|
||||||
|
extern cursor_rows
|
||||||
|
extern cursor_cols
|
||||||
|
|
||||||
|
global running_in_tty
|
||||||
|
running_in_tty: RESB 1
|
||||||
|
|
||||||
|
section .rodata
|
||||||
|
extern resetLen
|
||||||
|
|
||||||
|
hide_cursor: db ESC_CHAR, "[?25l", 0
|
||||||
|
show_cursor: db ESC_CHAR, "[?25h", 0
|
||||||
|
|
||||||
|
help_text: db "asm-game-of-life [args]",0xA,"-h display this help menu",0xA,"Controls:",0xA,"use arrow keys to move around",0xA,"ENTER to invert cell",0xA,"p to START/STOP simulation",0xA,"k to increase simulation speed",0xA,"j to decrese simulation speed",0xA, 0
|
||||||
|
|
||||||
section .text
|
section .text
|
||||||
global _start
|
extern print_str
|
||||||
|
extern unsigned_int_to_ascii
|
||||||
|
extern init_alloc
|
||||||
|
extern alloc
|
||||||
|
|
||||||
unsigned_int_to_acii: ; takes value stored in rdi
|
extern init_gameboard
|
||||||
push rdx
|
extern print_game_ui
|
||||||
push r12
|
|
||||||
push r13
|
|
||||||
|
|
||||||
mov r12, rdi
|
extern handle_user_input
|
||||||
|
|
||||||
mov rax,SYS_BRK
|
extern disable_canonical_mode_and_echo
|
||||||
mov rdi,0
|
extern reset_terminal
|
||||||
syscall
|
|
||||||
mov [heap_ptr], rax
|
|
||||||
|
|
||||||
mov r13, 0
|
global _start
|
||||||
mov rax, r12
|
_start:
|
||||||
mov rcx, 10
|
; get terminal dimensions
|
||||||
.count_loop:
|
mov rax, SYS_IOCTL
|
||||||
inc r13
|
mov rdi, STDOUT
|
||||||
cmp rax, 10
|
mov rsi, TIOCGWINSZ
|
||||||
jl .loop_exit
|
lea rdx, [multipurpuse_buf]
|
||||||
|
syscall
|
||||||
|
|
||||||
xor rdx, rdx
|
mov word ax, [multipurpuse_buf]; rows are stored at offset 0
|
||||||
div rcx
|
mov [term_rows], ax
|
||||||
push rdx
|
|
||||||
jmp .count_loop
|
|
||||||
|
|
||||||
.loop_count_exit:
|
mov word ax, [multipurpuse_buf+2]; cols are stored at offset 2
|
||||||
push rax
|
mov [term_cols], ax
|
||||||
|
|
||||||
mov rdi, [heap_ptr]
|
; handle args
|
||||||
add rdi, r13
|
pop rcx; get argc (number of arguments)
|
||||||
inc rdi
|
pop rax; get rid of program name arugument
|
||||||
mov rax, SYS_BRK
|
cmp rcx, 1
|
||||||
syscall
|
jle .no_arguments_provided
|
||||||
|
dec rcx
|
||||||
|
.handle_arg:
|
||||||
|
pop rax
|
||||||
|
mov word di, [rax]
|
||||||
|
|
||||||
mov rdi [heap_ptr]
|
cmp di, 0x682D; check if -h was passed
|
||||||
mov rcx 0
|
jne .next_arg
|
||||||
.store_loop: ; basicly for loop
|
lea rdi, [help_text]
|
||||||
cmp rcx, rdi
|
call print_str
|
||||||
jnl .loop_store_exit
|
jmp .exit_program
|
||||||
|
|
||||||
pop rax
|
.next_arg:
|
||||||
add rax, ASCII_ZERO
|
dec rcx
|
||||||
|
test rcx, rcx
|
||||||
|
jnz .handle_arg
|
||||||
|
|
||||||
mov rdx rdi
|
.no_arguments_provided:
|
||||||
add rdx rcx
|
|
||||||
mov byte rdx, rax
|
|
||||||
|
|
||||||
inc rcx
|
|
||||||
jmp .store_loop
|
|
||||||
|
|
||||||
.loop_store_exit
|
pop rax; get rid of null termination of argv
|
||||||
add rdi rcx
|
; handle enviroment vars
|
||||||
mov byte rdi, 0
|
|
||||||
|
.handle_env:
|
||||||
|
pop rax
|
||||||
|
test rax, rax; test if we reached end of envs
|
||||||
|
jz .no_envs
|
||||||
|
|
||||||
|
mov dword edi, [rax]
|
||||||
|
cmp edi, 0x4D524554; check for "TERM" inverted becose endiannes
|
||||||
|
jne .handle_env
|
||||||
|
mov qword rdi, [rax+5]; remove the TERM= part this should never segfault since there sould allwas be other data behind enviroment vars and i dont mind garbage
|
||||||
|
mov rsi, 0xffffffffff
|
||||||
|
and rdi, rsi
|
||||||
|
mov rsi, 0x78756e696c
|
||||||
|
cmp rdi, rsi; check for "linux"
|
||||||
|
jne .no_envs
|
||||||
|
mov byte [running_in_tty], 1
|
||||||
|
|
||||||
|
.no_envs:
|
||||||
|
|
||||||
|
|
||||||
|
call init_alloc
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
xor rcx, rcx
|
||||||
|
|
||||||
|
mov ax, [term_rows]
|
||||||
|
mov cx, [term_cols]
|
||||||
|
mul rcx
|
||||||
|
mov rdi, rax
|
||||||
|
mov qword [gameboard_size], rax
|
||||||
|
inc rdi; addition byte for NULL BYTE
|
||||||
|
lea rax, [resetLen]
|
||||||
|
add rdi, rax
|
||||||
|
add rdi, ESC_chars_compensation_Len
|
||||||
|
call alloc
|
||||||
|
mov [gameboard_ptr], rax; stores pointer to gameboard array
|
||||||
|
call init_gameboard
|
||||||
|
|
||||||
|
; make stdin non-blocking in case polling somehow fails, or am i stupid
|
||||||
|
mov rax, SYS_FCNTL
|
||||||
|
mov rdi, STDIN
|
||||||
|
mov rsi, F_SETFL
|
||||||
|
mov rdx, O_NONBLOCK
|
||||||
|
syscall
|
||||||
|
|
||||||
|
lea rdi, [hide_cursor]
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
call print_game_ui
|
||||||
|
|
||||||
|
call disable_canonical_mode_and_echo
|
||||||
|
|
||||||
|
call print_game_ui
|
||||||
|
|
||||||
|
call handle_user_input
|
||||||
|
|
||||||
|
call reset_terminal
|
||||||
|
|
||||||
|
lea rdi, [show_cursor]
|
||||||
|
call print_str
|
||||||
|
|
||||||
|
.exit_program:
|
||||||
|
mov rax, SYS_EXIT
|
||||||
|
mov rdi, 0 ; return code
|
||||||
|
syscall
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print_str: ; takes pointer to string in rdi and retuns in rax
|
|
||||||
push rsi
|
|
||||||
push rdx
|
|
||||||
mov rsi, rdi
|
|
||||||
|
|
||||||
mov rdx, 0
|
|
||||||
.count_loop:
|
|
||||||
cmp byte [rsi+rdx], 0
|
|
||||||
je .print
|
|
||||||
inc rdx
|
|
||||||
jmp .count_loop
|
|
||||||
|
|
||||||
.print:
|
|
||||||
mov rax,SYS_WRITE
|
|
||||||
mov rdi,STDOUT
|
|
||||||
syscall
|
|
||||||
|
|
||||||
pop rdx
|
|
||||||
pop rsi
|
|
||||||
ret
|
|
||||||
|
|
||||||
print_at_pos:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_start:
|
|
||||||
mov rdi,clear
|
|
||||||
call print_str
|
|
||||||
|
|
||||||
mov rdi,hello
|
|
||||||
call print_str
|
|
||||||
|
|
||||||
mov rdi,test
|
|
||||||
call print_str
|
|
||||||
|
|
||||||
mov rax,SYS_EXIT
|
|
||||||
mov rdi,0; return code
|
|
||||||
syscall
|
|
||||||
|
|||||||
+169
@@ -0,0 +1,169 @@
|
|||||||
|
%include "symbols.asm"
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
global print_str
|
||||||
|
print_str: ; takes pointer to string in rdi and retuns in rax
|
||||||
|
push rsi
|
||||||
|
push rdx
|
||||||
|
mov rsi, rdi
|
||||||
|
xor rdx, rdx
|
||||||
|
|
||||||
|
.count_loop:
|
||||||
|
cmp byte [rsi+rdx], 0
|
||||||
|
je .print
|
||||||
|
inc rdx
|
||||||
|
jmp .count_loop
|
||||||
|
|
||||||
|
.print:
|
||||||
|
mov rax, SYS_WRITE
|
||||||
|
mov rdi, STDOUT
|
||||||
|
syscall
|
||||||
|
pop rdx
|
||||||
|
pop rsi
|
||||||
|
ret
|
||||||
|
|
||||||
|
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
|
||||||
|
xor r11, r11
|
||||||
|
mov rcx, 10
|
||||||
|
mov rax, rsi
|
||||||
|
|
||||||
|
.count_loop:
|
||||||
|
inc r11
|
||||||
|
cmp rax, 10
|
||||||
|
jl .loop_count_exit
|
||||||
|
xor rdx, rdx
|
||||||
|
div rcx
|
||||||
|
push rdx
|
||||||
|
jmp .count_loop
|
||||||
|
|
||||||
|
.loop_count_exit:
|
||||||
|
push rax
|
||||||
|
|
||||||
|
xor rcx, rcx
|
||||||
|
|
||||||
|
.store_loop: ; basicly for loop
|
||||||
|
cmp rcx, r11
|
||||||
|
jnl .loop_store_exit
|
||||||
|
|
||||||
|
pop rax
|
||||||
|
add rax, ASCII_ZERO
|
||||||
|
mov byte [rdi + rcx], al
|
||||||
|
inc rcx
|
||||||
|
|
||||||
|
jmp .store_loop
|
||||||
|
|
||||||
|
.loop_store_exit:
|
||||||
|
|
||||||
|
mov rax, r11
|
||||||
|
|
||||||
|
ret
|
||||||
|
|
||||||
|
global string_copy
|
||||||
|
string_copy:; takes pointer to destination in rdi and pointer to source in rsi and return lenght in rax
|
||||||
|
|
||||||
|
xor rax, rax
|
||||||
|
xor rcx, rcx
|
||||||
|
.copy_next_byte:
|
||||||
|
mov byte cl, [rsi+rax]
|
||||||
|
test cl, cl
|
||||||
|
jz .exit
|
||||||
|
mov [rdi+rax], cl
|
||||||
|
inc rax
|
||||||
|
jmp .copy_next_byte
|
||||||
|
|
||||||
|
.exit:
|
||||||
|
ret
|
||||||
|
|
||||||
|
global memory_set:
|
||||||
|
memory_set:; takes destination in rdi, byte in sil and lenght in rdx
|
||||||
|
; first check if value is 16 byte alligned
|
||||||
|
|
||||||
|
mov r9, rdi; move destination to r9
|
||||||
|
|
||||||
|
mov r11, 0x0101010101010101; to extend across whoule register
|
||||||
|
movzx rsi, sil
|
||||||
|
imul r11, rsi; to extend across whoule register
|
||||||
|
|
||||||
|
cmp rdx, 16
|
||||||
|
jnl .write_16_or_more_bytes
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
test al, al; check if resault is 0
|
||||||
|
jz .addr_is_16_Byte_alligned
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
.write_less_than_16_bytes:
|
||||||
|
mov rax, r11
|
||||||
|
sub rdx, rcx; we will write these bytes now
|
||||||
|
|
||||||
|
rep stosb
|
||||||
|
|
||||||
|
.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
|
||||||
|
|
||||||
|
%ifdef AVX512
|
||||||
|
vpbroadcastq xmm8, r11
|
||||||
|
%else
|
||||||
|
movq xmm8, r11
|
||||||
|
shufpd xmm8, xmm8, 0x00
|
||||||
|
%endif
|
||||||
|
|
||||||
|
.move_16_bytes:
|
||||||
|
movdqa [rdi], xmm8
|
||||||
|
add rdi, 16
|
||||||
|
sub rdx, 16
|
||||||
|
|
||||||
|
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
|
||||||
|
mov cl, dl
|
||||||
|
jmp .write_less_than_16_bytes
|
||||||
|
|
||||||
|
.true_function_exit:
|
||||||
|
mov rax, r9; return pointer to memory area same as memset in libc
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
global memory_copy:
|
||||||
|
memory_copy:; takes destination in rdi, source in rsi and lenght in rdx
|
||||||
|
; first check if value is 16 byte alligned
|
||||||
|
|
||||||
|
mov r9, rdi
|
||||||
|
|
||||||
|
mov rcx, rdx
|
||||||
|
shr rcx, 3; calculate how many 8 byte chunks we need
|
||||||
|
and rdx, 0x7; calculate the reminder
|
||||||
|
|
||||||
|
rep movsq; move as many 8 byte chunks as posible
|
||||||
|
|
||||||
|
mov rcx, rdx
|
||||||
|
|
||||||
|
rep movsb; move the rest
|
||||||
|
|
||||||
|
|
||||||
|
mov rax, r9; return pointer to memory area same as memcpy in libc
|
||||||
|
ret
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
SYS_EXIT equ 60
|
||||||
|
SYS_IOCTL equ 16
|
||||||
|
SYS_READ equ 0
|
||||||
|
SYS_WRITE equ 1
|
||||||
|
SYS_BRK equ 12
|
||||||
|
SYS_FCNTL equ 72
|
||||||
|
SYS_POLL equ 7
|
||||||
|
SYS_NANOSLEEP equ 35
|
||||||
|
|
||||||
|
STDIN equ 0
|
||||||
|
STDOUT equ 1
|
||||||
|
|
||||||
|
TIOCGWINSZ equ 0x5413
|
||||||
|
TCGETS equ 0x5401
|
||||||
|
TCSETS equ 0x5402
|
||||||
|
F_SETFL equ 4
|
||||||
|
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
|
||||||
|
ESC_CHAR equ 27
|
||||||
|
|
||||||
|
ESC_chars_compensation_Len equ 9; i have to compensate for escape sequences that dont get printed why 11 exactly, I dont know
|
||||||
Reference in New Issue
Block a user