developer #1
229
ASM_CHEATSHEET.md
Normal file
229
ASM_CHEATSHEET.md
Normal file
@ -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.
|
||||
221
src/main.asm
221
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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user