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
|