You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
8.2 KiB
337 lines
8.2 KiB
%macro print_format 1 |
|
lea si, [%1] |
|
call _print_format |
|
%endmacro |
|
%macro print_format 2 |
|
lea si, [%1] |
|
push %2 |
|
call _print_format |
|
add sp, 2 |
|
%endmacro |
|
%macro print_format 3 |
|
lea si, [%1] |
|
push %3 |
|
push %2 |
|
call _print_format |
|
add sp, 4 |
|
%endmacro |
|
%macro print_format 4 |
|
lea si, [%1] |
|
push %4 |
|
push %3 |
|
push %2 |
|
call _print_format |
|
add sp, 6 |
|
%endmacro |
|
%macro print_format 5 |
|
lea si, [%1] |
|
push %5 |
|
push %4 |
|
push %3 |
|
push %2 |
|
call _print_format |
|
add sp, 8 |
|
%endmacro |
|
%macro print_format 6 |
|
lea si, [%1] |
|
push %6 |
|
push %5 |
|
push %4 |
|
push %3 |
|
push %2 |
|
call _print_format |
|
add sp, 10 |
|
%endmacro |
|
%macro print_format 7 |
|
lea si, [%1] |
|
push %7 |
|
push %6 |
|
push %5 |
|
push %4 |
|
push %3 |
|
push %2 |
|
call _print_format |
|
add sp, 12 |
|
%endmacro |
|
|
|
|
|
BITS 16 |
|
|
|
dumpmem_hardcoded_args: |
|
mov si, sp |
|
mov si, [si] |
|
mov cx, 400 |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dumpmem: |
|
; Dumps memory |
|
; IN 'si': Start address to dump from |
|
; IN 'cx': Number of bytes do dump |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
pusha |
|
|
|
xor edx, edx |
|
|
|
.loop: |
|
mov ax, word [esi + 2*edx] |
|
inc edx |
|
call dumpax |
|
mov ax, (0xE<<8)|' ' ; print space |
|
int 0x10 |
|
loop .loop |
|
.end: |
|
|
|
popa |
|
ret |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dumpax: |
|
; Prints the contens of ax as a hexadecimal number |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
pusha ; save registers |
|
mov dx, ax |
|
mov ah, 0xE ; Teletype output |
|
|
|
mov cx, 4 ; 4 nibbles in a 16 bit word |
|
.print_loop: |
|
rol dx, 4 ; rotate to next nibble |
|
mov al, dl ; we copy to al because we need to mask only the low 4 bits |
|
and al, 0xF ; Do the masking |
|
add al, '0' ; convert to ASCII |
|
|
|
; If we are greater than 9 ascii... |
|
cmp al, '9' |
|
jbe .skip_diff_to_ascii_A |
|
add al, 'A'-('9'+1) ; ...add 7 to make digits 10 to 15 be represented as 'A' to 'F' |
|
.skip_diff_to_ascii_A: |
|
|
|
int 0x10 ; BIOS call 'output' |
|
loop .print_loop |
|
|
|
popa ; restore registers |
|
ret |
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dumpax10: |
|
; Prints the contens of ax as a decimal number |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
pusha |
|
|
|
mov bx, 10 ; Divisor |
|
|
|
xor cx, cx ; Digit count starts at 0 |
|
|
|
.loop_divide: ; finds digits and pushes them to stack |
|
test ax, ax |
|
jz .break_loop_divide |
|
xor dx, dx |
|
div bx ; dx = (dx:ax)%bx, ax = (dx:ax)/bx |
|
push dx |
|
inc cx ; Increase digit count |
|
jmp .loop_divide |
|
.break_loop_divide: |
|
|
|
.loop_print: |
|
pop ax |
|
add al, '0' ; Convert to ascii |
|
mov ah, 0xE |
|
int 0x10 |
|
loop .loop_print |
|
|
|
popa |
|
ret |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dumpax_char: |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
mov ah, 0xE |
|
int 0x10 |
|
ret |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
keyprint: |
|
; Enters a loop where the keycode of each pressed key is printed |
|
; [ESC] exits the loop |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
pusha |
|
|
|
mov si, .f_info |
|
call print |
|
|
|
.keyprint_loop: |
|
mov ax, 0x1000 ; BIOS call to wait for key |
|
int 0x16 |
|
|
|
mov bx, ax ; Save KeyCode in bx |
|
|
|
print_format .f, ax, ax |
|
|
|
cmp bx, 0x011B ; ESC key |
|
je .break_keyprint_loop |
|
|
|
jmp .keyprint_loop |
|
.break_keyprint_loop: |
|
|
|
popa |
|
ret |
|
.f_info: db 13, 10, "Press keys to see their keycodes.",13,10,"Press [ESC] to exit.", 13, 10, 0 |
|
.f: db "(%c: %x)", 13, 10, 0 |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dump_stack_registers: |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
push si |
|
print_format .format_string, sp, bp |
|
pop si |
|
ret |
|
.format_string: db "StackRegisters(SP:%x BP:%x)", 0 |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dump_general_registers: |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
push si |
|
print_format .format_string, ax, cx, dx, bx, si, di |
|
pop si |
|
ret |
|
.format_string: db "GeneralRegisters(ax:%x cx:%x dx:%x bx:%x si:%x di:%x)", 0 |
|
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dump_segment_registers: |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
push si |
|
print_format .format_string, ss, cs, ds, es, fs, gs |
|
pop si |
|
ret |
|
.format_string: db "SegmentRegisters(Stack:%x Code:%x Data:%x Extra:%x F:%x G:%x)", 0 |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
_print_format: |
|
; IN: variable number of 16-bit numbers on stack |
|
; IN: 'si' points to beginning of format string with the following format: |
|
; %x in string replaced with hexadecimal representation |
|
; %d in string replaced with decimal representation |
|
; %% in string replaced with literal % sign |
|
; |
|
; EXAMPLE call: |
|
; push word 1337 |
|
; push word 0xbeef |
|
; push word 0xdead |
|
; lea si, [.FORMAT] |
|
; call print_format ; output: "(DEAD-BEEF){1337} 100%" |
|
; add sp, 6 |
|
; (...) |
|
; .FORMAT: db "(%x-%x){%d} 100%%",0 |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
push bp |
|
mov bp, sp |
|
pushf |
|
pusha |
|
|
|
lea bp, [bp+4] |
|
|
|
.outer_loop: |
|
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function |
|
|
|
.print_loop: |
|
lodsb ; al = *si++ |
|
cmp al, '%' |
|
je .break_print |
|
test al, al |
|
jz .break_outer |
|
int 0x10 |
|
jmp .print_loop |
|
.break_print: |
|
|
|
lodsb |
|
cmp al, 'x' |
|
je .format_hex |
|
cmp al, 'd' |
|
je .format_dec |
|
cmp al, 'c' |
|
je .format_char |
|
cmp al, '%' |
|
je .print_literal_percent |
|
|
|
.format_hex: |
|
lea cx, [dumpax] |
|
jmp .print_ax |
|
.format_dec: |
|
lea cx, [dumpax10] |
|
jmp .print_ax |
|
.format_char: |
|
lea cx, [dumpax_char] |
|
|
|
.print_ax: |
|
mov ax, [bp] |
|
lea bp, [bp+2] |
|
call cx |
|
jmp .outer_loop |
|
|
|
.print_literal_percent: |
|
mov ax, (0xE<<8)|'%' |
|
int 0x10 |
|
jmp .outer_loop |
|
.break_outer: |
|
|
|
popa |
|
popf |
|
pop bp |
|
ret |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dump_dx_as_two_chars: |
|
; IN dh: first char |
|
; IN dl: second char |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
push ax |
|
mov ah, 0xE |
|
mov al, dh |
|
int 0x10 |
|
mov al, dl |
|
int 0x10 |
|
pop ax |
|
ret |
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
dump_status_flags: |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
pushf |
|
push si |
|
push ax |
|
push bx |
|
|
|
lahf |
|
mov bl, ah |
|
|
|
lea si, [.flags_string] |
|
|
|
mov ah, 0xE ; Specify 'int 0x10' 'teletype output' function |
|
|
|
.outer_loop: |
|
; [AL = Character, BH = Page Number, BL = Colour (in graphics mode)] |
|
.print_loop: |
|
lodsb ; Load byte at address SI into AL, and increment SI |
|
cmp al, '%' |
|
je .break_print_loop ; If the character is zero (NUL), stop writing the string |
|
test al, al |
|
jz .break_outer_loop |
|
int 0x10 ; Otherwise, print the character via 'int 0x10' |
|
jmp .print_loop ; Repeat for the next character |
|
.break_print_loop: |
|
|
|
ror bl, 1 |
|
mov al, bl |
|
and al, 1 |
|
add al, '0' |
|
int 0x10 |
|
jmp .outer_loop |
|
|
|
.break_outer_loop: |
|
|
|
pop bx |
|
pop ax |
|
pop si |
|
popf |
|
ret |
|
.flags_string: db "Flags(Sign:% Zero:% ?:% Adjust:% ?:% Parity:% ?:% Carry:%)", 0 |