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