diff --git a/ASM_CHEATSHEET.md b/ASM_CHEATSHEET.md new file mode 100644 index 0000000..25745d7 --- /dev/null +++ b/ASM_CHEATSHEET.md @@ -0,0 +1,229 @@ +# Registers + +## General Purpose + +| Register | Usage | +|----------|--------------------------------------------| +| rax | Accumulator for general use and syscall number | +| eax | Lower 32 bits of rax | +| ax | Lower 16 bits of rax | +| al | Lower 8 bits of ax | +| rbx | Base register | +| ebx | Lower 32 bits of rbx | +| bx | Lower 16 bits of rbx | +| bl | Lower 8 bits of bx | +| rcx | Counter register (loops) | +| ecx | Lower 32 bits of rcx | +| cx | Lower 16 bits of rcx | +| cl | Lower 8 bits of cx | +| rdx | Data register | +| edx | Lower 32 bits of rdx | +| dx | Lower 16 bits of rdx | +| dl | Lower 8 bits of dx | + +## Index and Pointer + +| Register | Usage | +|----------|--------------------------------------------| +| rsi | Source for data (string operations) | +| esi | Lower 32 bits of rsi | +| si | Lower 16 bits of rsi | +| sil | Lower 8 bits of si | +| rdi | Destination for data | +| edi | Lower 32 bits of rdi | +| di | Lower 16 bits of rdi | +| dil | Lower 8 bits of di | +| rsp | Stack pointer | +| esp | Lower 32 bits of rsp | +| sp | Lower 16 bits of rsp | +| spl | Lower 8 bits of sp | +| rbp | Base pointer for stack frames | +| ebp | Lower 32 bits of rbp | +| bp | Lower 16 bits of rbp | +| bpl | Lower 8 bits of bp | + +## Extended + +| Register | Usage | +|----------|--------------------------------------------| +| r8–r15 | Extra general-purpose registers | +| r8d–r15d | Lower 32 bits of r8–r15 | +| r8w–r15w | Lower 16 bits of r8–r15 | +| r8b–r15b | Lower 8 bits of r8–r15 | + +# Data Movement + +| Command | Description | +|-------------------|------------------------------------------| +| mov dest, src | Copy data from src to dest | +| movzx dest, src | Zero-extend src into dest | +| movsx dest, src | Sign-extend src into dest | +| lea dest, [addr] | Load effective address into dest | +| rel addr | Relative address | +| push src | Push value of src onto the stack | +| pop dest | Pop value from the stack into dest | +| pusa | Pushes all registers to the stack | +| popa | Pops all registers from the stack | +| xchg dest, src | Exchange values of dest and src | +| cmovcc dest, src | Conditional move | +| movs dest, src | Move string | +| movsb | Move byte from [rsi] to [rdi] | +| movsw | Move word from [rsi] to [rdi] | +| movsd | Move doubleword from [rsi] to [rdi] | +| movsq | Move quadword from [rsi] to [rdi] | + +# Arithmetic + +| Command | Description | +|-------------------|------------------------------------------| +| add dest, src | Add src to dest | +| sub dest, src | Subtract src from dest | +| imul dest, src | Multiply dest by src (signed) | +| mul src | Multiply rax by src (result in rdx:rax) | +| idiv src | Divide rdx:rax by src (quotient in rax, remainder in rdx) | +| xor dest, src | XOR (useful for clearing, e.g., xor rax, rax) | +| inc reg | Increment reg by 1 | +| dec reg | Decrement reg by 1 | +| adc dest, src | Add with carry | +| sbb dest, src | Subtract with borrow | +| neg dest | Negate (two's complement) | +| div src | Unsigned divide rdx:rax by src | +| cbw | Convert byte to word | +| cwd | Convert word to doubleword | +| cdq | Convert doubleword to quadword | +| cqo | Convert quadword to octword | + +# Logical + +| Command | Description | +|-------------------|------------------------------------------| +| and dest, src | Bitwise AND | +| or dest, src | Bitwise OR | +| xor dest, src | Bitwise XOR | +| not dest | Bitwise NOT | +| shl dest, imm | Shift bits in dest left by imm | +| shr dest, imm | Shift bits in dest right by imm | +| sal dest, imm | Arithmetic shift left | +| sar dest, imm | Arithmetic shift right | +| rol dest, imm | Rotate bits left | +| ror dest, imm | Rotate bits right | +| rcl dest, imm | Rotate through carry left | +| rcr dest, imm | Rotate through carry right | +| test dest, src | Test bits (AND without storing result) | + +# Control Flow + +| Command | Description | +|-------------------|------------------------------------------| +| jmp label | Unconditional jump to label | +| cmp op1, op2 | Compare op1 and op2 | +| je label | Jump if equal | +| jne label | Jump if not equal | +| jg label | Jump if greater (signed) | +| jl label | Jump if less (signed) | +| jge label | Jump if greater or equal (signed) | +| jle label | Jump if less or equal (signed) | +| ja label | Jump if above (unsigned) | +| jb label | Jump if below (unsigned) | +| jae label | Jump if above or equal (unsigned) | +| jbe label | Jump if below or equal (unsigned) | +| call label | Call a function at label | +| ret | Return from a function | +| loop label | Loop to label | +| loope label | Loop while equal | +| loopne label | Loop while not equal | +| jecxz label | Jump if ecx is zero | +| jrcxz label | Jump if rcx is zero | + +# Syscall Interface (Linux/macOS) + +| Register | Description | +|----------|--------------------------------------------------| +| rax | Syscall number | +| rdi | First argument | +| rsi | Second argument | +| rdx | Third argument | +| r10 | Fourth argument | +| r8 | Fifth argument | +| r9 | Sixth argument | + +# Common Syscall Numbers + +| Syscall | rax | Description | +|-----------|-----------|--------------------------------------| +| sys_exit | 0x2000001 | Exit program | +| sys_write | 0x2000004 | Write to file descriptor | +| sys_read | 0x2000003 | Read from file descriptor | + +# Stack Manipulation + +| Command | Description | +|-----------|--------------------------------------------------| +| push reg | Push register value onto the stack | +| pop reg | Pop top of stack into register | +| call addr | Call a subroutine at addr | +| ret | Return from subroutine | +| enter imm, imm | Create stack frame | +| leave | Destroy stack frame | + +# String Operations + +| Command | Description | +|-----------|--------------------------------------------------| +| movsb | Move byte from [rsi] to [rdi] | +| movsw | Move word from [rsi] to [rdi] | +| movsd | Move doubleword from [rsi] to [rdi] | +| movsq | Move quadword from [rsi] to [rdi] | +| stosb | Store byte from al to [rdi] | +| stosw | Store word from ax to [rdi] | +| stosd | Store doubleword from eax to [rdi] | +| stosq | Store quadword from rax to [rdi] | +| lodsb | Load byte from [rsi] into al | +| lodsw | Load word from [rsi] into ax | +| lodsd | Load doubleword from [rsi] into eax | +| lodsq | Load quadword from [rsi] into rax | +| scasb | Scan byte in al against [rdi] | +| scasw | Scan word in ax against [rdi] | +| scasd | Scan doubleword in eax against [rdi] | +| scasq | Scan quadword in rax against [rdi] | +| cmpsb | Compare byte at [rsi] with byte at [rdi] | +| cmpsw | Compare word at [rsi] with word at [rdi] | +| cmpsd | Compare doubleword at [rsi] with doubleword at [rdi] | +| cmpsq | Compare quadword at [rsi] with quadword at [rdi] | + +# Data Definition + +| Command | Description | +|-----------|--------------------------------------------------| +| db value | Define byte (1 byte) | +| dw value | Define word (2 bytes) | +| dd value | Define doubleword (4 bytes) | +| dq value | Define quadword (8 bytes) | +| dt value | Define ten bytes (80 bits) | + +# Examples: + + assembly: + + section .data + byteVar db 0x1 ; Define a byte variable + wordVar dw 0x1234 ; Define a word variable + dwordVar dd 0x12345678 ; Define a doubleword variable + qwordVar dq 0x123456789ABCDEF0 ; Define a quadword variable + + section .text + global main + + main: + mov al, [byteVar] ; Move byteVar into al + mov ax, [wordVar] ; Move wordVar into ax + mov eax, [dwordVar] ; Move dwordVar into eax + mov rax, [qwordVar] ; Move qwordVar into rax + + +# Tips for Debugging + +- Use xor rax, rax or mov rax, 0 to zero out rax. +- Use comments liberally to track which registers hold what values! +- Step through your code with gdb or an equivalent debugger to watch registers change. +- If things seem off, double-check your mov, cmp, and syscall logic. diff --git a/bin/main b/bin/main index 5830395..a2765ae 100755 Binary files a/bin/main and b/bin/main differ diff --git a/src/main.asm b/src/main.asm index cd1f7c0..01f2526 100644 --- a/src/main.asm +++ b/src/main.asm @@ -1,19 +1,226 @@ section .data - + tile_emply db "[ ]", 0 + tile_len equ $ - tile_emply + + tile_emply_dummie db "[ ]", 0 + + tile_flag db "[!]", 0 + tile_mine db "[x]", 0 + + user_location db "[*]", 0 + + user_location_pos db 0 + + user_input times 3 db 0 + user_input_len equ $ - user_input + + + newline db 0xA, 0 + newline_len equ $ - newline + digit_buffer db 0 + section .bss + board resb 100 section .text global _main _main: + ; Fill the board with 0s and 1s + xor r10, r10 ; Counter + lea r11, [rel board] ; Load address of board - ; Lets create a 2D array of 10x10 - ; 0 = empty - ; 1 = bomb - ; 2 > number of bombs around + mov rcx, 100 ; Loop 100 times +fill_loop: + rdrand rax + and rax, 15 ; Reduce probability of mine (1 in 16 chance) + cmp rax, 1 + sete al ; Set al to 1 if rax == 1, otherwise 0 + mov [r11 + r10], al ; Store at board[r10] + inc r10 + loop fill_loop + ; Print the board + xor r10, r10 ; Reset counter + +print_loop: + xor rcx , rcx ; Reset mine count + lea r11, [rel board] + movzx rax, byte [r11 + r10] ; Load board[r10] - mov rax, 0x2000001 ; syscall: exit - xor rdi, rdi ; status: 0 + ; Print user location + cmp r10, [rel user_location_pos] + jne not_user_location + lea r8, [rel user_location] + mov r9, tile_len + call print_String + jmp next_tile + +not_user_location: + + ; Check if the tile is a mine + cmp rax, 1 + jne not_mine + + ; Print mine + lea r8, [rel tile_mine] + mov r9, tile_len + call print_String + jmp next_tile + +not_mine: + ; Check if the tile is near a mine + ; int3 ; Insert a breakpoint for GDB + call count_adjacent_mines + cmp dl, 0 + je print_empty + + ; Print number of adjacent mines properly using tile_emply. + lea rdi, [rel tile_emply_dummie] ; Load address of "[ ]" + add dl, '0' ; Convert count to ASCII + mov byte [rdi+1], dl ; Overwrite middle character with digit + mov r8, rdi + mov r9, tile_len + call print_String + jmp next_tile + +print_empty: + ; Print empty tile + lea r8, [rel tile_emply] + mov r9, tile_len + call print_String + jmp next_tile + +next_tile: + ; Check if newline is needed (every 10th element) + cmp r10, 0 + je no_newline + + mov rax, r10 + inc rax + xor rdx, rdx + mov rbx, 10 + div rbx + test rdx, rdx ; Check if remainder is 0 + jnz no_newline ; If not, don't print newline + lea r8, [rel newline] + mov r9, newline_len + call print_String + +no_newline: + inc r10 + cmp r10, 100 + jb print_loop + + ; Read arrow keys + ; Exit + mov rax, 0x2000001 + xor rdi, rdi syscall +; r8 = string +; r9 = length +print_String: + mov rax, 0x2000004 + mov rdi, 1 + mov rsi, r8 + mov rdx, r9 + syscall + ret + +; r10 = current tile index +; r11 = board +; rdx = mine count +; r8 = offset +count_adjacent_mines: + xor rdx, rdx + mov r8, 0 + + ; Check top left + mov rax, r10 + sub rax, 11 + cmp rax, 0 + jl .skip_top_left + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_top_left: + + ; Check top + mov rax, r10 + sub rax, 10 + cmp rax, 0 + jl .skip_top + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_top: + + ; Check top right + mov rax, r10 + sub rax, 9 + cmp rax, 0 + jl .skip_top_right + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_top_right: + + ; Check left + mov rax, r10 + sub rax, 1 + cmp rax, 0 + jl .skip_left + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_left: + + ; Check right + mov rax, r10 + add rax, 1 + cmp rax, 100 + jge .skip_right + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_right: + + ; Check bottom left + mov rax, r10 + add rax, 9 + cmp rax, 100 + jge .skip_bottom_left + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_bottom_left: + + ; Check bottom + mov rax, r10 + add rax, 10 + cmp rax, 100 + jge .skip_bottom + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_bottom: + + ; Check bottom right + mov rax, r10 + add rax, 11 + cmp rax, 100 + jge .skip_bottom_right + movzx rax, byte [r11 + rax] + cmp rax, 1 + sete al + add dl, al +.skip_bottom_right: + ret