From 377bd03fe514559bdcb7ef2db0527fc960d0dc7f Mon Sep 17 00:00:00 2001 From: Hayden Chow <kin3.chow@live.uwe.ac.uk> Date: Thu, 10 Oct 2024 12:53:46 +0100 Subject: [PATCH] test --- asm_io.asm | 502 ++++++++++++++++++++++++++++++++++++++++++++++++ Task.cpp => src | 0 worksheet1.asm | 22 +++ 3 files changed, 524 insertions(+) create mode 100644 asm_io.asm rename Task.cpp => src (100%) create mode 100644 worksheet1.asm diff --git a/asm_io.asm b/asm_io.asm new file mode 100644 index 0000000..ad52628 --- /dev/null +++ b/asm_io.asm @@ -0,0 +1,502 @@ +; +; 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_TYPE +segment .data public align=4 class=data use32 +%else +segment .data +%endif + +int_format db "%i", 0 +string_format db "%s", 0 +reg_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 0 +carry_flag db "CF", 0 +zero_flag db "ZF", 0 +sign_flag db "SF", 0 +parity_flag db "PF", 0 +overflow_flag db "OF", 0 +dir_flag db "DF", 0 +aux_carry_flag db "AF", 0 +unset_flag db " ", 0 +mem_format1 db "Memory Dump # %d Address = %.8X", NL, 0 +mem_format2 db "%.8X ", 0 +mem_format3 db "%.2X ", 0 +stack_format db "Stack Dump # %d", NL + db "EBP = %.8X ESP = %.8X", NL, 0 +stack_line_format db "%+4d %.8X %.8X", NL, 0 +math_format1 db "Math Coprocessor Dump # %d Control Word = %.4X" + db " Status Word = %.4X", NL, 0 +valid_st_format db "ST%d: %.10g", NL, 0 +invalid_st_format db "ST%d: Invalid ST", NL, 0 +empty_st_format db "ST%d: Empty", NL, 0 + +; +; code is put in the _TEXT segment +; +%ifdef OBJ_TYPE +segment text public align=1 class=code use32 +%else +segment .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, _putchar + +read_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 + ret + +print_int: + enter 0,0 + pusha + pushf + + push eax + push dword int_format + call _printf + pop ecx + pop ecx + + popf + popa + leave + ret + +print_string: + enter 0,0 + pusha + pushf + + push eax + push dword string_format + call _printf + pop ecx + pop ecx + + popf + popa + leave + ret + +read_char: + enter 4,0 + pusha + pushf + + call _getchar + mov [ebp-4], eax + + popf + popa + mov eax, [ebp-4] + leave + ret + +print_char: + enter 0,0 + pusha + pushf + +%ifndef WATCOM + push eax +%endif + call _putchar +%ifndef WATCOM + pop ecx +%endif + + popf + popa + leave + ret + + +print_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 + ret + + +sub_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_cf +cf_off: + mov eax, unset_flag +push_cf: + push eax + + test dword [ebp-4], PF_MASK + jz pf_off + mov eax, parity_flag + jmp short push_pf +pf_off: + mov eax, unset_flag +push_pf: + push eax + + test dword [ebp-4], AF_MASK + jz af_off + mov eax, aux_carry_flag + jmp short push_af +af_off: + mov eax, unset_flag +push_af: + push eax + + test dword [ebp-4], ZF_MASK + jz zf_off + mov eax, zero_flag + jmp short push_zf +zf_off: + mov eax, unset_flag +push_zf: + push eax + + test dword [ebp-4], SF_MASK + jz sf_off + mov eax, sign_flag + jmp short push_sf +sf_off: + mov eax, unset_flag +push_sf: + push eax + + test dword [ebp-4], DF_MASK + jz df_off + mov eax, dir_flag + jmp short push_df +df_off: + mov eax, unset_flag +push_df: + push eax + + test dword [ebp-4], OF_MASK + jz of_off + mov eax, overflow_flag + jmp short push_of +of_off: + mov eax, unset_flag +push_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 4 + +sub_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 display + +stack_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 12 + + +sub_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 ecx +mem_outer_loop: + push ecx + push esi + push dword mem_format2 + call _printf + add esp, 8 + + xor ebx, ebx +mem_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, ebx +mem_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_continue +non_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 counter +tag_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_loop +zero_st: + fldz + jmp short print_real +valid_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_loop +invalid_st: + push edi + push dword invalid_st_format + call _printf + add esp, 8 +cont_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 diff --git a/Task.cpp b/src similarity index 100% rename from Task.cpp rename to src diff --git a/worksheet1.asm b/worksheet1.asm new file mode 100644 index 0000000..1ff3aeb --- /dev/null +++ b/worksheet1.asm @@ -0,0 +1,22 @@ +%include “asm_io.inc” +segment .data +integer1 dd 15 ; first int + integer2 dd 6 ; second int +segment .bss +result resd 1 ; result +segment .text +global asm_main +asm_main: +pusha +mov eax, [integer1] ; eax = int1 +add eax, [integer2] ; eax = int1 + int2 +mov [result], eax ; result = int1 + int2 +call print_int ; print result + popa +mov eax, 0 + +% nasm -f elf one.asm -o one.o + +% gcc -m32 -c driver.c -o driver.o + +% gcc -m32 driver.o one.o asm_io.o -o a.out \ No newline at end of file -- GitLab