📄 asm_io.asm
字号:
;; file: asm_io.asm; Assembly I/O routines; To assemble for DJGPP; nasm -f coff -d COFF_TYPE asm_io.asm; To assemble for Borland C++ 5.x; nasm -f obj -d OBJ_TYPE asm_io.asm; To assemble for Microsoft Visual Studio; nasm -f win32 -d COFF_TYPE asm_io.asm; To assemble for Linux; nasm -f elf -d ELF_TYPE asm_io.asm; To assemble for Watcom; nasm -f obj -d OBJ_TYPE -d WATCOM asm_io.asm; IMPORTANT NOTES FOR WATCOM; The Watcom compiler's C library does not use the; standard C calling convention. For example, the; putchar() function gets its argument from the; the value of EAX, not the stack.%define NL 10%define CF_MASK 00000001h%define PF_MASK 00000004h%define AF_MASK 00000010h%define ZF_MASK 00000040h%define SF_MASK 00000080h%define DF_MASK 00000400h%define OF_MASK 00000800h;; Linux C doesn't put underscores on labels;%ifdef ELF_TYPE %define _scanf scanf %define _printf printf %define _getchar getchar %define _putchar putchar%endif;; Watcom puts underscores at end of label;%ifdef WATCOM %define _scanf scanf_ %define _printf printf_ %define _getchar getchar_ %define _putchar putchar_%endif%ifdef OBJ_TYPEsegment .data public align=4 class=data use32%elsesegment .data%endifint_format db "%i", 0string_format db "%s", 0reg_format db "Register Dump # %d", NL db "EAX = %.8X EBX = %.8X ECX = %.8X EDX = %.8X", NL db "ESI = %.8X EDI = %.8X EBP = %.8X ESP = %.8X", NL db "EIP = %.8X FLAGS = %.4X %s %s %s %s %s %s %s", NL db 0carry_flag db "CF", 0zero_flag db "ZF", 0sign_flag db "SF", 0parity_flag db "PF", 0overflow_flag db "OF", 0dir_flag db "DF", 0aux_carry_flag db "AF", 0unset_flag db " ", 0mem_format1 db "Memory Dump # %d Address = %.8X", NL, 0mem_format2 db "%.8X ", 0mem_format3 db "%.2X ", 0stack_format db "Stack Dump # %d", NL db "EBP = %.8X ESP = %.8X", NL, 0stack_line_format db "%+4d %.8X %.8X", NL, 0math_format1 db "Math Coprocessor Dump # %d Control Word = %.4X" db " Status Word = %.4X", NL, 0valid_st_format db "ST%d: %.10g", NL, 0invalid_st_format db "ST%d: Invalid ST", NL, 0empty_st_format db "ST%d: Empty", NL, 0;; code is put in the _TEXT segment;%ifdef OBJ_TYPEsegment text public align=1 class=code use32%elsesegment .text%endif global read_int, print_int, print_string, read_char global print_char, print_nl, sub_dump_regs, sub_dump_mem global sub_dump_math, sub_dump_stack extern _scanf, _printf, _getchar, _putcharread_int: enter 4,0 pusha pushf lea eax, [ebp-4] push eax push dword int_format call _scanf pop ecx pop ecx popf popa mov eax, [ebp-4] leave retprint_int: enter 0,0 pusha pushf push eax push dword int_format call _printf pop ecx pop ecx popf popa leave retprint_string: enter 0,0 pusha pushf push eax push dword string_format call _printf pop ecx pop ecx popf popa leave retread_char: enter 4,0 pusha pushf call _getchar mov [ebp-4], eax popf popa mov eax, [ebp-4] leave retprint_char: enter 0,0 pusha pushf%ifndef WATCOM push eax%endif call _putchar%ifndef WATCOM pop ecx%endif popf popa leave retprint_nl: enter 0,0 pusha pushf%ifdef WATCOM mov eax, 10 ; WATCOM doesn't use the stack here%else push dword 10 ; 10 == ASCII code for \n%endif call _putchar%ifndef WATCOM pop ecx%endif popf popa leave retsub_dump_regs: enter 4,0 pusha pushf mov eax, [esp] ; read FLAGS back off stack mov [ebp-4], eax ; save flags;; show which FLAGS are set; test eax, CF_MASK jz cf_off mov eax, carry_flag jmp short push_cfcf_off: mov eax, unset_flagpush_cf: push eax test dword [ebp-4], PF_MASK jz pf_off mov eax, parity_flag jmp short push_pfpf_off: mov eax, unset_flagpush_pf: push eax test dword [ebp-4], AF_MASK jz af_off mov eax, aux_carry_flag jmp short push_afaf_off: mov eax, unset_flagpush_af: push eax test dword [ebp-4], ZF_MASK jz zf_off mov eax, zero_flag jmp short push_zfzf_off: mov eax, unset_flagpush_zf: push eax test dword [ebp-4], SF_MASK jz sf_off mov eax, sign_flag jmp short push_sfsf_off: mov eax, unset_flagpush_sf: push eax test dword [ebp-4], DF_MASK jz df_off mov eax, dir_flag jmp short push_dfdf_off: mov eax, unset_flagpush_df: push eax test dword [ebp-4], OF_MASK jz of_off mov eax, overflow_flag jmp short push_ofof_off: mov eax, unset_flagpush_of: push eax push dword [ebp-4] ; FLAGS mov eax, [ebp+4] sub eax, 10 ; EIP on stack is 10 bytes ahead of orig push eax ; EIP lea eax, [ebp+12] push eax ; original ESP push dword [ebp] ; original EBP push edi push esi push edx push ecx push ebx push dword [ebp-8] ; original EAX push dword [ebp+8] ; # of dump push dword reg_format call _printf add esp, 76 popf popa leave ret 4sub_dump_stack: enter 0,0 pusha pushf lea eax, [ebp+20] push eax ; original ESP push dword [ebp] ; original EBP push dword [ebp+8] ; # of dump push dword stack_format call _printf add esp, 16 mov ebx, [ebp] ; ebx = original ebp mov eax, [ebp+16] ; eax = # dwords above ebp shl eax, 2 ; eax *= 4 add ebx, eax ; ebx = & highest dword in stack to display mov edx, [ebp+16] mov ecx, edx add ecx, [ebp+12] inc ecx ; ecx = # of dwords to displaystack_line_loop: push edx push ecx ; save ecx & edx push dword [ebx] ; value on stack push ebx ; address of value on stack mov eax, edx sal eax, 2 ; eax = 4*edx push eax ; offset from ebp push dword stack_line_format call _printf add esp, 16 pop ecx pop edx sub ebx, 4 dec edx loop stack_line_loop popf popa leave ret 12sub_dump_mem: enter 0,0 pusha pushf push dword [ebp+12] push dword [ebp+16] push dword mem_format1 call _printf add esp, 12 mov esi, [ebp+12] ; address and esi, 0FFFFFFF0h ; move to start of paragraph mov ecx, [ebp+8] inc ecxmem_outer_loop: push ecx push esi push dword mem_format2 call _printf add esp, 8 xor ebx, ebxmem_hex_loop: xor eax, eax mov al, [esi + ebx] push eax push dword mem_format3 call _printf add esp, 8 inc ebx cmp ebx, 16 jl mem_hex_loop mov eax, '"' call print_char xor ebx, ebxmem_char_loop: xor eax, eax mov al, [esi+ebx] cmp al, 32 jl non_printable cmp al, 126 jg non_printable jmp short mem_char_loop_continuenon_printable: mov eax, '?'mem_char_loop_continue: call print_char inc ebx cmp ebx, 16 jl mem_char_loop mov eax, '"' call print_char call print_nl add esi, 16 pop ecx loop mem_outer_loop popf popa leave ret 12; function sub_dump_math; prints out state of math coprocessor without modifying the coprocessor; or regular processor state; Parameters:; dump number - dword at [ebp+8]; Local variables:; ebp-108 start of fsave buffer; ebp-116 temp double; Notes: This procedure uses the Pascal convention.; fsave buffer structure:; ebp-108 control word; ebp-104 status word; ebp-100 tag word; ebp-80 ST0; ebp-70 ST1; ebp-60 ST2 ...; ebp-10 ST7;sub_dump_math: enter 116,0 pusha pushf fsave [ebp-108] ; save coprocessor state to memory mov eax, [ebp-104] ; status word and eax, 0FFFFh push eax mov eax, [ebp-108] ; control word and eax, 0FFFFh push eax push dword [ebp+8] push dword math_format1 call _printf add esp, 16;; rotate tag word so that tags in same order as numbers are; in the stack; mov cx, [ebp-104] ; ax = status word shr cx, 11 and cx, 7 ; cl = physical state of number on stack top mov bx, [ebp-100] ; bx = tag word shl cl,1 ; cl *= 2 ror bx, cl ; move top of stack tag to lowest bits mov edi, 0 ; edi = stack number of number lea esi, [ebp-80] ; esi = address of ST0 mov ecx, 8 ; ecx = loop countertag_loop: push ecx mov ax, 3 and ax, bx ; ax = current tag or ax, ax ; 00 -> valid number je valid_st cmp ax, 1 ; 01 -> zero je zero_st cmp ax, 2 ; 10 -> invalid number je invalid_st push edi ; 11 -> empty push dword empty_st_format call _printf add esp, 8 jmp short cont_tag_loopzero_st: fldz jmp short print_realvalid_st: fld tword [esi]print_real: fstp qword [ebp-116] push dword [ebp-112] push dword [ebp-116] push edi push dword valid_st_format call _printf add esp, 16 jmp short cont_tag_loopinvalid_st: push edi push dword invalid_st_format call _printf add esp, 8cont_tag_loop: ror bx, 2 ; mov next tag into lowest bits inc edi add esi, 10 ; mov to next number on stack pop ecx loop tag_loop frstor [ebp-108] ; restore coprocessor state popf popa leave ret 4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -