您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

341 行
8.3 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:
push ds ; THIS IS ALSO HACKY
mov si, sp
mov ax, ss
mov ds, ax
;mov si, [si]
mov cx, 256
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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
pop ds ; THIS IS ONLY FOR DEBUG - REMOVE REMOVE REMOVE
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