Add sources
This commit is contained in:
parent
f5934d26a3
commit
8117e581ea
|
@ -0,0 +1,14 @@
|
||||||
|
# x86life: a life simulating game
|
||||||
|
# <https://git.luca0n.com/luca0N/x86life>
|
||||||
|
|
||||||
|
PROGRAM_NAME=x86life
|
||||||
|
ASM=nasm
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
$(PROGRAM_NAME): src/life.asm src/commonio_read.asm src/commonio_write.asm
|
||||||
|
$(ASM) -f elf64 -g -F dwarf -o $(PROGRAM_NAME).o src/life.asm
|
||||||
|
$(LD) $(PROGRAM_NAME).o -o $(PROGRAM_NAME)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -fv $(PROGRAM_NAME) $(PROGRAM_NAME).o
|
|
@ -0,0 +1,35 @@
|
||||||
|
; x86life: a life simulating game
|
||||||
|
; Copyright (C) 2023-2024 luca0N!
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, version 3 of the License.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; <https://git.luca0n.com/luca0N/x86life>
|
||||||
|
; Contact: <https://www.luca0n.com/en/contact>
|
||||||
|
|
||||||
|
.read:
|
||||||
|
; read digit stdin
|
||||||
|
XOR RAX, RAX
|
||||||
|
XOR RDI, RDI
|
||||||
|
SYSCALL
|
||||||
|
|
||||||
|
; remove line feed, if present
|
||||||
|
DEC RAX
|
||||||
|
ADD RSI, RAX
|
||||||
|
CMP [RSI], BYTE 0x0A
|
||||||
|
JNE .read_ret
|
||||||
|
MOV [RSI], BYTE 0x00
|
||||||
|
.read_ret:
|
||||||
|
SUB RSI, RAX
|
||||||
|
RET
|
||||||
|
|
||||||
|
; vim: syntax=nasm ts=4 sw=4 et
|
|
@ -0,0 +1,36 @@
|
||||||
|
; x86life: a life simulating game
|
||||||
|
; Copyright (C) 2023-2024 luca0N!
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, version 3 of the License.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; <https://git.luca0n.com/luca0N/x86life>
|
||||||
|
; Contact: <https://www.luca0n.com/en/contact>
|
||||||
|
|
||||||
|
.print:
|
||||||
|
CALL .print_getLen
|
||||||
|
.printLen:
|
||||||
|
MOV RAX, 1
|
||||||
|
MOV RDI, 1
|
||||||
|
SYSCALL
|
||||||
|
RET
|
||||||
|
|
||||||
|
.print_getLen:
|
||||||
|
MOV RDX, RSI
|
||||||
|
.print_getLen_loop:
|
||||||
|
INC RDX
|
||||||
|
CMP [RDX], BYTE 0x00
|
||||||
|
JNE .print_getLen_loop
|
||||||
|
SUB RDX, RSI
|
||||||
|
RET
|
||||||
|
|
||||||
|
; vim: syntax=nasm ts=4 sw=4 et
|
|
@ -0,0 +1,158 @@
|
||||||
|
; x86life: a life simulating game
|
||||||
|
; Copyright (C) 2023-2024 luca0N!
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, version 3 of the License.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; <https://git.luca0n.com/luca0N/x86life>
|
||||||
|
; Contact: <https://www.luca0n.com/en/contact>
|
||||||
|
|
||||||
|
%include "src/commonio_write.asm"
|
||||||
|
%include "src/commonio_read.asm"
|
||||||
|
%include "src/printno.asm"
|
||||||
|
|
||||||
|
%define SYS_EXIT 60
|
||||||
|
%DEFINE PROTAGONIST_NAME_LEN 31
|
||||||
|
%DEFINE PROT_BUF_OFFSET_AGE 31
|
||||||
|
|
||||||
|
; The maximum age of the protagonist. Since we're using 7 bits for the age,
|
||||||
|
; this needs to be 127 (7Fh).
|
||||||
|
%DEFINE PROT_AGE_MAX 7Fh
|
||||||
|
|
||||||
|
SECTION .data
|
||||||
|
buf_protagonist: ; protagonist buffer. 31 bytes for
|
||||||
|
TIMES 32 DB 0 ; the name, 1 for age
|
||||||
|
buf_in: ; stdin buffer
|
||||||
|
TIMES 32 DB 0
|
||||||
|
buf_age:
|
||||||
|
TIMES 3 DB 0
|
||||||
|
|
||||||
|
SECTION .rodata
|
||||||
|
str_newln:
|
||||||
|
DB 0x0A, 0x00
|
||||||
|
str_intro:
|
||||||
|
DB "Welcome to Life!", 0x0A, "Insert the name of the ", \
|
||||||
|
"protagonist: ", 0x00
|
||||||
|
str_intro_name_invalid:
|
||||||
|
DB "The protagonist name must be within 1-32 boundaries.", \
|
||||||
|
0x0A, 0x00
|
||||||
|
str_game_dead:
|
||||||
|
DB "The protagonist has died at an age of: ", 0x00
|
||||||
|
|
||||||
|
str_birth:
|
||||||
|
DB "The protagonist was born today!", 0x0A, 0x00
|
||||||
|
str_birthday_1:
|
||||||
|
DB "Today, ", 0x00
|
||||||
|
str_birthday_2:
|
||||||
|
DB " turns ", 0x00
|
||||||
|
str_birthday_3:
|
||||||
|
DB "!", 0x0A, 0x00
|
||||||
|
str_continue:
|
||||||
|
DB "Press any key to age. ", 0x00
|
||||||
|
|
||||||
|
SECTION .text
|
||||||
|
GLOBAL _start
|
||||||
|
_start:
|
||||||
|
MOV RSI, str_intro ; print intro msg
|
||||||
|
CALL .print
|
||||||
|
MOV RSI, buf_protagonist ; read to buffer from stdin
|
||||||
|
MOV RDX, PROT_BUF_OFFSET_AGE
|
||||||
|
CALL .read
|
||||||
|
PUSH RAX
|
||||||
|
CMP RAX, 32 ; check whether the user send more
|
||||||
|
; data than the buffer could hold
|
||||||
|
JE .invalidNameBounds
|
||||||
|
|
||||||
|
POP RAX
|
||||||
|
CMP RAX, 2
|
||||||
|
JLE .invalidNameBounds
|
||||||
|
|
||||||
|
; Begin the game!!
|
||||||
|
MOV RSI, str_birth
|
||||||
|
CALL .print
|
||||||
|
|
||||||
|
.begin:
|
||||||
|
; Check whether the protagonist is still alive
|
||||||
|
; ============================================
|
||||||
|
; Alive/dead status is represented by the most
|
||||||
|
; significant bit in the age byte
|
||||||
|
MOV RAX, [buf_protagonist + PROT_BUF_OFFSET_AGE]
|
||||||
|
AND RAX, 80h
|
||||||
|
CMP RAX, 80h
|
||||||
|
JE .protDead
|
||||||
|
|
||||||
|
; Print age header
|
||||||
|
; ================
|
||||||
|
MOV RSI, str_birthday_1 ; "Today, "
|
||||||
|
CALL .print
|
||||||
|
MOV RSI, buf_protagonist ; (protagonist)
|
||||||
|
CALL .print
|
||||||
|
MOV RSI, str_birthday_2 ; " turns "
|
||||||
|
CALL .print
|
||||||
|
|
||||||
|
MOV RSI, buf_age ; (age)
|
||||||
|
MOV RAX, [buf_protagonist + PROT_BUF_OFFSET_AGE]
|
||||||
|
CALL .getHumanReadableNum ; (n)
|
||||||
|
MOV RSI, buf_age
|
||||||
|
MOV RDX, 3
|
||||||
|
CALL .printLen
|
||||||
|
|
||||||
|
MOV RSI, str_birthday_3 ; (!)
|
||||||
|
CALL .print
|
||||||
|
|
||||||
|
MOV RSI, str_continue
|
||||||
|
CALL .print
|
||||||
|
LEA RSI, [buf_protagonist + PROT_BUF_OFFSET_AGE]
|
||||||
|
MOV RAX, [RSI]
|
||||||
|
INC RAX
|
||||||
|
CMP RAX, PROT_AGE_MAX
|
||||||
|
JNE .begin_continue
|
||||||
|
OR RAX, 80h ; kill protagonist
|
||||||
|
.begin_continue:
|
||||||
|
MOV [RSI], RAX
|
||||||
|
MOV RSI, buf_in
|
||||||
|
MOV RDX, 1
|
||||||
|
CALL .read
|
||||||
|
|
||||||
|
JMP .begin
|
||||||
|
.protDead:
|
||||||
|
; Subroutine: the protagonist has died
|
||||||
|
; ====================================
|
||||||
|
MOV RSI, str_game_dead
|
||||||
|
CALL .print
|
||||||
|
MOV RSI, buf_age ; (age)
|
||||||
|
MOV RAX, [buf_protagonist + PROT_BUF_OFFSET_AGE]
|
||||||
|
AND RAX, 7Fh ; get rid of life bit
|
||||||
|
CALL .getHumanReadableNum
|
||||||
|
MOV RSI, buf_age
|
||||||
|
MOV RDX, 3
|
||||||
|
CALL .printLen
|
||||||
|
MOV RSI, str_newln
|
||||||
|
CALL .print
|
||||||
|
JMP .exit
|
||||||
|
|
||||||
|
.invalidNameBounds:
|
||||||
|
; MOV RSI, buf_protagonist
|
||||||
|
; CALL .read ; keep reading until there is nothing
|
||||||
|
; CMP RAX, 0 ; more to read to prevent pending data
|
||||||
|
; JNE .nameTooBig ; from going to the buffer
|
||||||
|
|
||||||
|
MOV RSI, str_intro_name_invalid
|
||||||
|
CALL .print
|
||||||
|
JMP _start
|
||||||
|
|
||||||
|
.exit:
|
||||||
|
MOV RAX, SYS_EXIT
|
||||||
|
XOR RDI, RDI
|
||||||
|
SYSCALL
|
||||||
|
|
||||||
|
; vim: syntax=nasm ts=4 sw=4 et
|
|
@ -0,0 +1,63 @@
|
||||||
|
; x86life: a life simulating game
|
||||||
|
; Copyright (C) 2023-2024 luca0N!
|
||||||
|
;
|
||||||
|
; This program is free software: you can redistribute it and/or modify
|
||||||
|
; it under the terms of the GNU General Public License as published by
|
||||||
|
; the Free Software Foundation, version 3 of the License.
|
||||||
|
;
|
||||||
|
; This program is distributed in the hope that it will be useful,
|
||||||
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
; GNU General Public License for more details.
|
||||||
|
;
|
||||||
|
; You should have received a copy of the GNU General Public License
|
||||||
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
;
|
||||||
|
; <https://git.luca0n.com/luca0N/x86life>
|
||||||
|
; Contact: <https://www.luca0n.com/en/contact>
|
||||||
|
|
||||||
|
;SECTION .rodata
|
||||||
|
; num equ 20
|
||||||
|
;SECTION .data
|
||||||
|
; buf times 3 db 20h
|
||||||
|
;SECTION .text
|
||||||
|
; GLOBAL _start
|
||||||
|
.getHumanReadableNum:
|
||||||
|
; MOV AL, num ; put num on RAX
|
||||||
|
PUSH RAX ; save num on stack
|
||||||
|
MOV BL, 100 ; check for hundredth digit
|
||||||
|
DIV BL ; divide RAX by BL
|
||||||
|
CMP AL, 0
|
||||||
|
|
||||||
|
; MOV RSI, buf
|
||||||
|
ADD AL, 0x30 ; digit to ASCII
|
||||||
|
MOV [RSI], AL
|
||||||
|
|
||||||
|
SUB AL, 0x30
|
||||||
|
MUL BL ; multiply AL by BL
|
||||||
|
MOV BL, AL
|
||||||
|
POP RAX ; get original saved number
|
||||||
|
SUB AL, BL ; discard hundreds
|
||||||
|
|
||||||
|
PUSH RAX
|
||||||
|
MOV BL, 10
|
||||||
|
DIV BL ; get tenth digit
|
||||||
|
|
||||||
|
INC RSI ; next buffer byte
|
||||||
|
ADD AL, 0x30 ; digit to ASCII
|
||||||
|
MOV [RSI], AL
|
||||||
|
|
||||||
|
SUB AL, 0x30
|
||||||
|
MUL BL
|
||||||
|
MOV BL, AL
|
||||||
|
POP RAX
|
||||||
|
SUB AL, BL
|
||||||
|
|
||||||
|
INC RSI
|
||||||
|
ADD AL, 0x30
|
||||||
|
MOV [RSI], AL
|
||||||
|
|
||||||
|
SUB RSI, 2
|
||||||
|
RET
|
||||||
|
|
||||||
|
; vim: syntax=nasm ts=4 sw=4 et
|
Loading…
Reference in New Issue