From 7a6799d2c775a0320d059d7d420e15cb31015099 Mon Sep 17 00:00:00 2001 From: Ed94 Date: Tue, 18 Jan 2022 08:15:28 -0500 Subject: [PATCH] initial commit --- .editorconfig | 36 +++ .gitignore | 0 .vscode/settings.json | 6 + 0.Hello/16bit.hello.TextModeBuff.hex | Bin 0 -> 512 bytes 0.Hello/16bit.hello.TextModeBuff.hex.s | 164 +++++++++++ 0.Hello/16bit.hello.char.TextModeBuff.s | 58 ++++ 0.Hello/16bit.hello.char.teletype.s | 60 ++++ 0.Hello/AAL.x86.s | 349 +++++++++++++++++++++++ 16bit copy.Scratch | Bin 0 -> 512 bytes 16bit.CheckDisplayMode.s | 53 ++++ 16bit.Scratch | Bin 0 -> 512 bytes 16bit.Scratch.s | 163 +++++++++++ AAL.x86.routines.macros.s | 43 +++ AAL.x86.routines.s | 117 ++++++++ AAL.x86.s | 362 ++++++++++++++++++++++++ Erus.boot.s | 79 ++++++ bare_x86.code-workspace | 8 + readme.md | 1 + 18 files changed, 1499 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 0.Hello/16bit.hello.TextModeBuff.hex create mode 100644 0.Hello/16bit.hello.TextModeBuff.hex.s create mode 100644 0.Hello/16bit.hello.char.TextModeBuff.s create mode 100644 0.Hello/16bit.hello.char.teletype.s create mode 100644 0.Hello/AAL.x86.s create mode 100644 16bit copy.Scratch create mode 100644 16bit.CheckDisplayMode.s create mode 100644 16bit.Scratch create mode 100644 16bit.Scratch.s create mode 100644 AAL.x86.routines.macros.s create mode 100644 AAL.x86.routines.s create mode 100644 AAL.x86.s create mode 100644 Erus.boot.s create mode 100644 bare_x86.code-workspace create mode 100644 readme.md diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..32df2dd --- /dev/null +++ b/.editorconfig @@ -0,0 +1,36 @@ +# root = true + +[*] +end_of_line = lf +insert_final_newline = true +guidelines = 160 + +[*{.h, .c}] +indent_style = tab +indent_size = 4 +guidelines = 160 + +[*{.low.h, .low.c] +indent_style = tab +indent_size = 8 +guidelines = 80 + +[*{.hpp, cpp}] +indent_style = tab +indent_size = 4 +guidelines = 160 + +[*{.low.hpp, .low.cpp}] +indent_style = tab +indent_size = 8 +guidelines = 80 + +[*{.py}] +indent_style = space +indent_size = 4 +guidelines = 180 + +[*[.s]] +indent_style = tab +indent_size = 8 +guidelines = 80 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..8929a4c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "editor.rulers": [ + 110, + ], + "editor.cursorStyle": "block-outline" +} diff --git a/0.Hello/16bit.hello.TextModeBuff.hex b/0.Hello/16bit.hello.TextModeBuff.hex new file mode 100644 index 0000000000000000000000000000000000000000..e9d8fba49a787804745c81d26c1ad608092e8307 GIT binary patch literal 512 zcmdnZP_u<$1M^t{!vlRc`VRD6=)ALAN#O+(!|Q*)5;|}0i>W#Iny2|Oe;31|{F=_w z2VZkQI0ax13xrb$<}g4wMKwEfYhFk(Bpx;}G%_|ZH8Z!cbaZldadl%bs4xHmhJ<|# i4BHvD@O7SU{>N6r-o 0b0100, 0b0001 -> 0b0000 + shr hex, 12 ; First four : 0x[#]### -> 0x000# + and hex, 0x0F ; Mask out any garbage + mov AL, [hex + SI] ; AL = hex + SI + mov [.Result + 2], AL ; result[2] = AL + + mov hex, backup ; Next four + shr hex, 8 + and hex, 0x0F + mov AL, [hex + SI] + mov [.Result + 3], AL + + mov hex, backup ; ... + shr hex, 4 + and hex, 0x0F + mov AL, [hex + SI] + mov [.Result + 4], AL + + mov hex, backup + shr hex, 0 + and hex, 0x0F + mov AL, [hex + SI] + mov [.Result + 5], AL + +; BX : String arg + mov CX, .Result +call output_String + +; Pop all register values that were saved on the current stack + popa +; Set Interrupt Flag : Restore interrupts + ret + +; Proc Data +.CharHex: +db '0123456789ABCDEF', 0x0 + +.Result: +db '0x0000', 0x0 + +%undef hex +%undef backup +%unmacro index 1 + + +;============================================================================================================= +; Output String to TextMode via Teletype +;============================================================================================================= +%define string CX +%define CharHex_Length 6 +%macro TextMode_SetChar 2 + mov word [%1 * 2 ], %2 + mov word [%1 * 2 + 1], 0x0F +%endmacro +output_String: + pusha +; Will track string index + mov SI, 0x0 + +; Prep BH and AH with Teletype video service option + mov BH, 0x0 + mov AH, Video_TeleType + +; Reg CX cannot be used as an index speciifer. [BX] is +; SI can be used as an offset inside [BX + offset] + mov BX, CX + +.loop: +; Compare + cmp SI, CharHex_Length + je .break +; Jump + +; Print via teletype + mov AL, [BX + SI]; +int VideoService + +; Increment index + inc SI + jmp short .loop + +.break: + popa + ret + +%undef string +%undef index +%undef CharHex_Length +%unmacro TextMode_SetChar 2 + + + +;============================================================================================================= +; Wrap up +;============================================================================================================= +; Byte pad 512 bytes (zeroed) +times 510-$+start db 0 +; Master Boot Record signature +db 0x55 +db 0xAA diff --git a/0.Hello/16bit.hello.char.TextModeBuff.s b/0.Hello/16bit.hello.char.TextModeBuff.s new file mode 100644 index 0000000..298f8ba --- /dev/null +++ b/0.Hello/16bit.hello.char.TextModeBuff.s @@ -0,0 +1,58 @@ +; Hello world. + +; x86 +; 16-bit - Real Mode, V86 Mode + +%include "AAL.x86.S" + + +; 16-Bit Mode +[BITS 16] +; The ORG directive specifies the starting address of a segment +[ORG Mem_BootSector_Start] + + +; A label to the address in memory +; Auto calculated by the assembler +start : + +textmode_ClearScreen : +; Params + mov AH, Video_SetMode + mov AL, VideoMode_Text_80x25 +; Call Interrupt +int VideoService + +; Set Data segment to the text mode's memory buffer +mov AX, Video_Text_MemBuffer +mov DS, AX + +%macro SetChar 2 + ; word : 16-bit (2-byte) increments + ; [offset] : specifies offset in Data Segment (DS) + ; Character + mov word [%1 * 2 ], %2 + ; Attributes - Low: Black, High: White + mov word [%1 * 2 + 1], 0x0F +%endmacro + SetChar 0x00, 'H' + SetChar 0x01, 'e' + SetChar 0x02, 'l' + SetChar 0x03, 'l' + SetChar 0x04, 'o' + SetChar 0x05, ' ' + SetChar 0x06, 'W' + SetChar 0x07, 'o' + SetChar 0x08, 'r' + SetChar 0x09, 'l' + SetChar 0x0A, 'd' + +hang : +jmp short hang + + +; Byte pad 512 bytes (zeroed) +times 510-$+start db 0 +; Master Boot Record signature +db 0x55 +db 0xAA diff --git a/0.Hello/16bit.hello.char.teletype.s b/0.Hello/16bit.hello.char.teletype.s new file mode 100644 index 0000000..fb53f74 --- /dev/null +++ b/0.Hello/16bit.hello.char.teletype.s @@ -0,0 +1,60 @@ +; Hello world. + +; x86 +; 16-bit - Real Mode, V86 Mode + +%include "AAL.x86.S" + + +; 16-Bit Mode +[BITS 16] +; The ORG directive specifies the starting address of a segment +[ORG Mem_BootSector_Start] + + +start : + +textmode_ClearScreen: +; Params + mov AH, Video_SetMode + mov AL, VideoMode_Text_40x25 +; Call Interrupt +int VideoService + +teletype_HelloWorld : + mov BH, 0x0 ; Make sure the Active page is the first + mov AH, Video_TeleType + mov AL, 'H' +int VideoService + mov AL, 'e' +int VideoService + mov AL, 'l' +int VideoService + mov AL, 'l' +int VideoService + mov AL, 'l' +int VideoService + mov AL, 'o' +int VideoService + mov AL, ' ' +int VideoService + mov AL, 'W' +int VideoService + mov AL, 'o' +int VideoService + mov AL, 'r' +int VideoService + mov AL, 'l' +int VideoService + mov AL, 'd' +int VideoService + +hang : +jmp short hang + + +; Byte pad 512 bytes (zeroed) +times 510-$+start db 0 +; Master Boot Record signature +db 0x55 +db 0xAA diff --git a/0.Hello/AAL.x86.s b/0.Hello/AAL.x86.s new file mode 100644 index 0000000..3e7104e --- /dev/null +++ b/0.Hello/AAL.x86.s @@ -0,0 +1,349 @@ +;============================================================================================================= +;============================================================================================================= +;============================================================================================================= +; AAL - Assembly Abstraction layer +; x86-64 +; Provides a suite of docs, functionatliy, macros, etc. +; +; Made while learning x86 +; Edward R. Gonzalez +;============================================================================================================= +;============================================================================================================= +;============================================================================================================= +; +; See +; https://en.wikibooks.org/wiki/X86_Assembly/16,_32,_and_64_Bits +; https://wiki.osdev.org/X86-64 +; http://www.ctyme.com/rbrown.htm +; https://github.com/Captainarash/The_Holy_Book_of_X86/blob/master/book_vol_1.txt + + +;============================================================================================================= +; Calling Convention +;============================================================================================================= +; Calling convention - Caller/Callee Saved Registers +; +; Caller rules: When calling a function the registers +; RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be saved into the stack +; by the caller, if it relies on them +; (unless otherwise safety-provable by analysis such as whole program optimization). +; +; Callee rules: +; RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 +; are considered nonvolatile and must be saved and restored from the stack by the callee if it modify them. +;============================================================================================================= +; END OF CALLING CONVENTION +;============================================================================================================= + +;============================================================================================================= +; Register Documentation +;============================================================================================================= +; General Purpose +; 8 High Low 16 32 64 Intended Purpose +; AH AL AX EAX RAX Accumulator +; BH BL BX EBX RBX Base +; CH CL CX ECX RCX Counter +; DH DL DX EDX RDX Data (Used to extend the A register) +; SIL SI ESI RSI Source index for strings ops +; DIL DI EDI RDI Destination index for string operations +; SPL SPL ESP RSP Stack pointer +; BPL BP EBP RBP Base pointer (meant for stack frames) +; R8B R8W R8D R8 General Purpose (and below) +; R9B R9W R9D R9 +; R10B R10W R10D R10 +; R11B R11W R11D R11 +; R12B R12W R12D R12 +; R13B R13W R13D R13 +; R14B R14W R14D R14 +; R15B R15W R15D R15 +; Instruction Pointer +; 16 32 64 +; IP EIP RIP +; Segment +; 16 +; CS Code Segment +; DS Data Segment +; SS Stack Segment +; ES Extra Segment +; FS General-purpose +; GS General-purpose +; RFLAGS +; Bit(s) Label Description +; 0 CF Carry Flag +; 1 1 Reserved +; 2 PF Parity Flag +; 3 0 Reserved +; 4 AF Auxiliary Carry Flag +; 5 0 Reserved +; 6 ZF Zero Flag +; 7 SF Sign Flag +; 8 TF Trap Flag +; 9 IF Interrupt Enable Flag +; 10 DF Direction Flag +; 11 OF Overflow Flag +; 12-13 IOPL I/O Privilege Level +; 14 NT Nested Task +; 15 0 Reserved +; 16 RF Resume Flag +; 17 VM Virtual-8086 Mode +; 18 AC Alignment Check / Access Control +; 19 VIF Virtual Interrupt Flag +; 20 VIP Virtual Interrupt Pending +; 21 ID ID Flag +; 22-63 0 Reserved + +; Control +; CR0 +; Bit(s) Label Description +; 0 PE Protected Mode Enable +; 1 MP Monitor Co-Processor +; 2 EM Emulation +; 3 TS Task Switched +; 4 ET Extension Type +; 5 NE Numeric Error +; 6-15 0 Reserved +; 16 WP Write Protect +; 17 0 Reserved +; 18 AM Alignment Mask +; 19-28 0 Reserved +; 29 NW Not-Write Through +; 30 CD Cache Disable +; 31 PG Paging +; 32-63 0 Reserved +; CR2 +; Contains the linear (virtual) address which triggered a page fault, available in the page fault's interrupt handler. +; +; CR3 +; Bit(s) Label Description Condition +; 0-11 0-2 0 Reserved CR4.PCIDE = 0 +; 3 PWT Page-Level Write Through +; 5 PCD Page-Level Cache Disable +; 5-11 0 Reserved +; 0-11 PCID CR4.PCIDE = 1 +; 12-63 Physical Base Address of the PML4 +; +; Note that this must be page aligned +; +; CR4 +; Bit(s) Label Description +; 0 VME Virtual-8086 Mode Extensions +; 1 PVI Protected Mode Virtual Interrupts +; 2 TSD Time Stamp enabled only in ring 0 +; 3 DE Debugging Extensions +; 4 PSE Page Size Extension +; 5 PAE Physical Address Extension +; 6 MCE Machine Check Exception +; 7 PGE Page Global Enable +; 8 PCE Performance Monitoring Counter Enable +; 9 OSFXSR OS support for fxsave and fxrstor instructions +; 10 OSXMMEXCPT OS Support for unmasked simd floating point exceptions +; 11 UMIP User-Mode Instruction Prevention (SGDT, SIDT, SLDT, SMSW, and STR are disabled in user mode) +; 12 0 Reserved +; 13 VMXE Virtual Machine Extensions Enable +; 14 SMXE Safer Mode Extensions Enable +; 15 0 Reserved +; 17 PCIDE PCID Enable +; 18 OSXSAVE XSAVE And Processor Extended States Enable +; 19 0 Reserved +; 20 SMEP Supervisor Mode Executions Protection Enable +; 21 SMAP Supervisor Mode Access Protection Enable +; 22 PKE Enable protection keys for user-mode pages +; 23 CET Enable Control-flow Enforcement Technology +; 24 PKS Enable protection keys for supervisor-mode pages +; 25-63 0 Reserved +; CR8 +; CR8 is a new register accessible in 64-bit mode using the REX prefix. +; CR8 is used to prioritize external interrupts and is referred to as the task-priority register (TPR). +; +; The AMD64 architecture allows software to define up to 15 external interrupt-priority classes. +; Priority classes are numbered from 1 to 15, with priority-class 1 being the lowest and priority-class 15 the highest. +; CR8 uses the four low-order bits for specifying a task priority and the remaining 60 bits are reserved and must be written with zeros. +; +; System software can use the TPR register to temporarily block low-priority interrupts from interrupting a high-priority task. +; This is accomplished by loading TPR with a value corresponding to the highest-priority interrupt that is to be blocked. +; For example, loading TPR with a value of 9 (1001b) blocks all interrupts with a priority class of 9 or less, +; while allowing all interrupts with a priority class of 10 or more to be recognized. +; Loading TPR with 0 enables all external interrupts. Loading TPR with 15 (1111b) disables all external interrupts. +; +; The TPR is cleared to 0 on reset. +; Bit Purpose +; 0-3 Priority +; 4-63 Reserved +; CR1, CR5-7, CR9-15 +; Reserved, the cpu will throw a #ud exeption when trying to access them. +; +; CR1, CR5-7, CR9-15 +; Reserved, the cpu will throw a #ud exeption when trying to access them. +; +; MSRs +; +; IA32_EFER +; Extended Feature Enable Register (EFER) is a model-specific register added in the AMD K6 processor, +; to allow enabling the SYSCALL/SYSRET instruction, and later for entering and exiting long mode. +; This register becomes architectural in AMD64 and has been adopted by Intel. Its MSR number is 0xC0000080. +; +; Bit(s) Label Description +; 0 SCE System Call Extensions +; 1-7 0 Reserved +; 8 LME Long Mode Enable +; 10 LMA Long Mode Active +; 11 NXE No-Execute Enable +; 12 SVME Secure Virtual Machine Enable +; 13 LMSLE Long Mode Segment Limit Enable +; 14 FFXSR Fast FXSAVE/FXRSTOR +; 15 TCE Translation Cache Extension +; 16-63 0 Reserved +; +; FS.base, GS.base +; +; MSRs with the addresses 0xC0000100 (for FS) and 0xC0000101 (for GS) contain the base addresses of the FS and GS segment registers. +; These are commonly used for thread-pointers in user code and CPU-local pointers in kernel code. Safe to contain anything, +; since use of a segment does not confer additional privileges to user code. +; +; In newer CPUs, these can also be written with WRFSBASE and WRGSBASE instructions at any privilege level. +; +; KernelGSBase +; MSR with the address 0xC0000102. +; Is basically a buffer that gets exchanged with GS.base after a swapgs instruction. +; Usually used to seperate kernel and user use of the GS register. +; +; Debug Registers +; +; DR0 - DR3 +; Contain linear addresses of up to 4 breakpoints. If paging is enabled, they are translated to physical addresses. +; DR6 +; It permits the debugger to determine which debug conditions have occured. +; When an enabled debug exception is enabled, low order bits 0-3 are set before entering debug exception handler. +; DR7 +; Bit Description +; 0 Local DR0 Breakpoint +; 1 Global DR0 Breakpoint +; 2 Local DR1 Breakpoint +; 3 Global DR1 Breakpoint +; 4 Local DR2 Breakpoint +; 5 Global DR2 Breakpoint +; 6 Local DR3 Breakpoint +; 7 Global DR3 Breakpoint +; 16-17 Conditions for DR0 +; 18-19 Size of DR0 Breakpoint +; 20-21 Conditions for DR1 +; 22-23 Size of DR1 Breakpoint +; 24-25 Conditions for DR2 +; 26-27 Size of DR2 Breakpoint +; 28-29 Conditions for DR3 +; 30-31 Size of DR3 Breakpoint +; +; A local breakpoint bit deactivates on hardware task switches, while a global does not. +; 00b condition means execution break, 01b means a write watchpoint, and 11b means an R/W watchpoint. +; 10b is reserved for I/O R/W (unsupported). +; +; Test Registers +; Name Description +; TR3 - TR5 Undocumented +; TR6 Test Command Register +; TR7 Test Data Register +; +; Protected Mode Registers +; GDTR +; +; Operand Size Label Description +; 64-bit 32-bit +; Bits 0-15 (Same) Limit Size of GDT +; Bits 16-79 Bits 16-47 Base Starting Address of GDT +; +; LDTR +; Stores the segment selector of the LDT. +; +; TR +; Stores the segment selector of the TSS. +; +; IDTR +; Operand Size Label Description +; 64-bit 32-bit +; Bits 0-15 (Same) Limit Size of IDT +; Bits 16-79 Bits 16-47 Base Starting Address of IDT +;============================================================================================================= +; END OF REGISTER DOCUMENTATION +;============================================================================================================= + +%ifndef AAL_x86_Def +;============================================================================================================= +; Instructions Library +;============================================================================================================= +; NO-Operation : Exchanges value of rax with rax to achieve nothing. +%define nop XCHG rax, rax +;============================================================================================================= +; END - Instructions Library +;============================================================================================================= + +;============================================================================================================= +; Interrupts +;============================================================================================================= +; BIOS + +; CX, DX Interval in microseconds +; CX : High, DX : Low +; SystemService +%define BIOS_Wait 0x86 + +; Memory + +; Real Mode - Conventional Lower Memory +%define Mem_RM_CLower_Start 0x0500 +%define Mem_RM_CLower_End 0x7BFF +; 2 Byte Boundary Alignment +%define Mem_RM_CLower_2BB_End 0x7BE0 + +; Real Mode - Conventional Upper memory +%define Mem_RM_CUpper_Start 0x7E00 +%define Mem_RM_CUpper_End 0x7FFF +; 2 Byte Boundary Alignment +%define Mem_RM_CUpper_2BB_End 0x7FE0 + +; Real Mode - OS Boot Sector +%define Mem_BootSector_Start 0x7C00 +%define Mem_BootSector_512 0x7CFE +%define Mem_BootSector_End 0x7DFF + +; Misc System Services +%define SystemService 0x15 + +; Video +%define VideoService 0x10 + +; Returns +; AH = Number of character columns +; AL = Display mode +; BH = Active Page +%define Video_GetCurrentMode 0x0F + +; Used to set the video mode. +%define Video_SetMode 0x00 + +; SetVideoMode - Modes +; cbOff : Color Burst Off +%define VideoMode_Text_40x25_cbOff 0x00 +%define VideoMode_Text_40x25 0x01 +%define VideoMode_Text_80x25_cbOff 0x02 +%define VideoMode_Text_80x25 0x03 +%define VideoMode_Graphics_320x200 0x04 +%define VideoMode_Graphics_320x200_cboff 0x05 +%define VideoMode_Graphics_640x200 0x06 + +; Output a character +%define Video_TeleType 0xE +; Where memory buffer for Video's Text mode starts +%define Video_Text_MemBuffer 0xB800 +;============================================================================================================= +; END - Interrupts +;============================================================================================================= + + +%define char_CR 0xD ; Carriage Return +%define char_LF 0xA ; Line Feed + + +%define AAL_x86_Def +%endif + + diff --git a/16bit copy.Scratch b/16bit copy.Scratch new file mode 100644 index 0000000000000000000000000000000000000000..da660c521dfb012ab8a7257b4f1d4a69ebaaf3a5 GIT binary patch literal 512 zcmdnOuz~rkfZ>6@8+`}*F6?Hg>AbT$taf2?ZNLjD#)vI#JDC{HitbLWU6>CP;b4sD z7AvgXSy~(T;vhq0w^(uQ&PpJAD?{Y&+S-M!KqXHZB6gS7?qFdEcySBJtb{PnGk}Z| z02;M}3n;URAz}wFkX{8;!BDe{f$0Sk!|Q*+VTRuMEuQfNNL*u}8;TMba*4h5hw$qYbeeX9X0*Fq?d0xJira0J^A@`~H* zIdRd485k6RAUL%1DbUX5e=H@kofn!P@Us}$Sk^JIuy@C?H6Lcy{M^BQ@Dz*N>w9sr z(T72bxA1kjv7HqF@*p}pZ*JkUE@LU-?L6JZVDSH}0MKQx-^Ilq4lXIm%u81YNi8nn j;^k%VNUeafxfrHMDk&I1K~QROX-6@8+`}*F6?Hg>AbT$taf2?ZNLjD#)vI#JDC{HitbLWU6>CP;b4sD z7AvgXSy~(T;vhq0w^(uQ&PpJAD?{Y&+S-M!KqXHZB6gS7?qFdEcySBJtb{PnGk}Z| z02;M}3n;URAz}wFkX{8;!BDe{f$0Sk!|Q*+VTRuMEuQfNNL*u}8;TMba*4h5hw$qYbeeX9X0*Fq?d0xJira0J^A@`~H* zIdRd485k6RAUL%1DbUX5e=H@kofn!P@Us}$Sk^JIuy@C?H6Lcy{M^BQ@Dz*N>w9sr z(T72bxA1kjv7HqF@*p}pZ*JkUE@LU-?L6JZVDSH}0MKQx-^Ilq4lXIm%u81YNi8nn j;^k%VNUeafxfrHMDk&I1K~QROX-9 (<= 0x39), A->F (>= 0x39) + cmp AL, 0x39 ; Numeral offset + jle .SetCharVal + add AL, 0x7 ; A-F offset + +.SetCharVal: +; Add the char value to the string + mov BX, [argStr] +; Move to last half-byte + add BX, 3 +; Go to the current half-byte via index offset + sub BX, SI +; Write ascii hex value to half-byte in ArgStr + mov [BX], AL +; Rotate the next half-byte over + ror DX, 4 + + inc SI + jmp .loop + +.break: + pop SI + pop BP + pop BX +%undef argStr +ret + + +; Print out an ASCII character. +out_char: +%define arg1 BP + 6 + push BX + push BP + mov BP, SP + + mov AH, Video_TeleType + mov AL, [arg1] +int VideoService + + pop BP + pop BX +%undef arg1 +ret + + +; Print out an ascii string of speicifed length +out_string: +; Arg - BX: String +%define argLen BP + 4 ; String Length +; Store previous state of BP and set it to SP + ; pusha ; 14 bytes + push BP ; 4 bytes + mov BP, SP +; Using the source index + push SI ; 0 bytes... + xor SI, SI + +; Backup BX for later + mov CX, BX + mov AH, Video_TeleType + +.loop: +; Bounds check + cmp SI, [argLen] + je .break + +; Output a character + mov BX, CX + mov AL, [BX + SI] + xor BH, BH ; Clear BH for correct active page +int VideoService + + add SI, 0x1 + jmp .loop + +.break: + pop SI + pop BP +%undef argLen +ret + + +%define AAL_routines_Def +%endif diff --git a/AAL.x86.s b/AAL.x86.s new file mode 100644 index 0000000..1e87daf --- /dev/null +++ b/AAL.x86.s @@ -0,0 +1,362 @@ +;============================================================================================================= +;============================================================================================================= +;============================================================================================================= +; AAL - Assembly Abstraction layer +; x86-64 +; Provides a suite of docs, functionatliy, macros, etc. +; +; Made while learning x86 +; Edward R. Gonzalez +;============================================================================================================= +;============================================================================================================= +;============================================================================================================= +; +; See +; https://en.wikibooks.org/wiki/X86_Assembly/16,_32,_and_64_Bits +; https://wiki.osdev.org/X86-64 +; http://www.ctyme.com/rbrown.htm +; https://github.com/Captainarash/The_Holy_Book_of_X86/blob/master/book_vol_1.txt + + +;============================================================================================================= +; Calling Convention +;============================================================================================================= +; Calling convention - Caller/Callee Saved Registers +; +; Caller rules: When calling a function the registers +; RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be saved into the stack +; by the caller, if it relies on them +; (unless otherwise safety-provable by analysis such as whole program optimization). +; +; Callee rules: +; RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 +; are considered nonvolatile and must be saved and restored from the stack by the callee if it modify them. +;============================================================================================================= +; END OF CALLING CONVENTION +;============================================================================================================= + +;============================================================================================================= +; Register Documentation +;============================================================================================================= +; General Purpose +; 8 High Low 16 32 64 Intended Purpose +; AH AL AX EAX RAX Accumulator +; BH BL BX EBX RBX Base +; CH CL CX ECX RCX Counter +; DH DL DX EDX RDX Data (Used to extend the A register) +; SIL SI ESI RSI Source index for strings ops +; DIL DI EDI RDI Destination index for string operations +; SPL SPL ESP RSP Stack pointer +; BPL BP EBP RBP Base pointer (meant for stack frames) +; R8B R8W R8D R8 General Purpose (and below) +; R9B R9W R9D R9 +; R10B R10W R10D R10 +; R11B R11W R11D R11 +; R12B R12W R12D R12 +; R13B R13W R13D R13 +; R14B R14W R14D R14 +; R15B R15W R15D R15 +; Instruction Pointer +; 16 32 64 +; IP EIP RIP +; Segment +; 16 +; CS Code Segment +; DS Data Segment +; SS Stack Segment +; ES Extra Segment +; FS General-purpose +; GS General-purpose +; RFLAGS +; Bit(s) Label Description +; 0 CF Carry Flag +; 1 1 Reserved +; 2 PF Parity Flag +; 3 0 Reserved +; 4 AF Auxiliary Carry Flag +; 5 0 Reserved +; 6 ZF Zero Flag +; 7 SF Sign Flag +; 8 TF Trap Flag +; 9 IF Interrupt Enable Flag +; 10 DF Direction Flag +; 11 OF Overflow Flag +; 12-13 IOPL I/O Privilege Level +; 14 NT Nested Task +; 15 0 Reserved +; 16 RF Resume Flag +; 17 VM Virtual-8086 Mode +; 18 AC Alignment Check / Access Control +; 19 VIF Virtual Interrupt Flag +; 20 VIP Virtual Interrupt Pending +; 21 ID ID Flag +; 22-63 0 Reserved + +; Control +; CR0 +; Bit(s) Label Description +; 0 PE Protected Mode Enable +; 1 MP Monitor Co-Processor +; 2 EM Emulation +; 3 TS Task Switched +; 4 ET Extension Type +; 5 NE Numeric Error +; 6-15 0 Reserved +; 16 WP Write Protect +; 17 0 Reserved +; 18 AM Alignment Mask +; 19-28 0 Reserved +; 29 NW Not-Write Through +; 30 CD Cache Disable +; 31 PG Paging +; 32-63 0 Reserved +; CR2 +; Contains the linear (virtual) address which triggered a page fault, available in the page fault's interrupt handler. +; +; CR3 +; Bit(s) Label Description Condition +; 0-11 0-2 0 Reserved CR4.PCIDE = 0 +; 3 PWT Page-Level Write Through +; 5 PCD Page-Level Cache Disable +; 5-11 0 Reserved +; 0-11 PCID CR4.PCIDE = 1 +; 12-63 Physical Base Address of the PML4 +; +; Note that this must be page aligned +; +; CR4 +; Bit(s) Label Description +; 0 VME Virtual-8086 Mode Extensions +; 1 PVI Protected Mode Virtual Interrupts +; 2 TSD Time Stamp enabled only in ring 0 +; 3 DE Debugging Extensions +; 4 PSE Page Size Extension +; 5 PAE Physical Address Extension +; 6 MCE Machine Check Exception +; 7 PGE Page Global Enable +; 8 PCE Performance Monitoring Counter Enable +; 9 OSFXSR OS support for fxsave and fxrstor instructions +; 10 OSXMMEXCPT OS Support for unmasked simd floating point exceptions +; 11 UMIP User-Mode Instruction Prevention (SGDT, SIDT, SLDT, SMSW, and STR are disabled in user mode) +; 12 0 Reserved +; 13 VMXE Virtual Machine Extensions Enable +; 14 SMXE Safer Mode Extensions Enable +; 15 0 Reserved +; 17 PCIDE PCID Enable +; 18 OSXSAVE XSAVE And Processor Extended States Enable +; 19 0 Reserved +; 20 SMEP Supervisor Mode Executions Protection Enable +; 21 SMAP Supervisor Mode Access Protection Enable +; 22 PKE Enable protection keys for user-mode pages +; 23 CET Enable Control-flow Enforcement Technology +; 24 PKS Enable protection keys for supervisor-mode pages +; 25-63 0 Reserved +; CR8 +; CR8 is a new register accessible in 64-bit mode using the REX prefix. +; CR8 is used to prioritize external interrupts and is referred to as the task-priority register (TPR). +; +; The AMD64 architecture allows software to define up to 15 external interrupt-priority classes. +; Priority classes are numbered from 1 to 15, with priority-class 1 being the lowest and priority-class 15 the highest. +; CR8 uses the four low-order bits for specifying a task priority and the remaining 60 bits are reserved and must be written with zeros. +; +; System software can use the TPR register to temporarily block low-priority interrupts from interrupting a high-priority task. +; This is accomplished by loading TPR with a value corresponding to the highest-priority interrupt that is to be blocked. +; For example, loading TPR with a value of 9 (1001b) blocks all interrupts with a priority class of 9 or less, +; while allowing all interrupts with a priority class of 10 or more to be recognized. +; Loading TPR with 0 enables all external interrupts. Loading TPR with 15 (1111b) disables all external interrupts. +; +; The TPR is cleared to 0 on reset. +; Bit Purpose +; 0-3 Priority +; 4-63 Reserved +; CR1, CR5-7, CR9-15 +; Reserved, the cpu will throw a #ud exeption when trying to access them. +; +; CR1, CR5-7, CR9-15 +; Reserved, the cpu will throw a #ud exeption when trying to access them. +; +; MSRs +; +; IA32_EFER +; Extended Feature Enable Register (EFER) is a model-specific register added in the AMD K6 processor, +; to allow enabling the SYSCALL/SYSRET instruction, and later for entering and exiting long mode. +; This register becomes architectural in AMD64 and has been adopted by Intel. Its MSR number is 0xC0000080. +; +; Bit(s) Label Description +; 0 SCE System Call Extensions +; 1-7 0 Reserved +; 8 LME Long Mode Enable +; 10 LMA Long Mode Active +; 11 NXE No-Execute Enable +; 12 SVME Secure Virtual Machine Enable +; 13 LMSLE Long Mode Segment Limit Enable +; 14 FFXSR Fast FXSAVE/FXRSTOR +; 15 TCE Translation Cache Extension +; 16-63 0 Reserved +; +; FS.base, GS.base +; +; MSRs with the addresses 0xC0000100 (for FS) and 0xC0000101 (for GS) contain the base addresses of the FS and GS segment registers. +; These are commonly used for thread-pointers in user code and CPU-local pointers in kernel code. Safe to contain anything, +; since use of a segment does not confer additional privileges to user code. +; +; In newer CPUs, these can also be written with WRFSBASE and WRGSBASE instructions at any privilege level. +; +; KernelGSBase +; MSR with the address 0xC0000102. +; Is basically a buffer that gets exchanged with GS.base after a swapgs instruction. +; Usually used to seperate kernel and user use of the GS register. +; +; Debug Registers +; +; DR0 - DR3 +; Contain linear addresses of up to 4 breakpoints. If paging is enabled, they are translated to physical addresses. +; DR6 +; It permits the debugger to determine which debug conditions have occured. +; When an enabled debug exception is enabled, low order bits 0-3 are set before entering debug exception handler. +; DR7 +; Bit Description +; 0 Local DR0 Breakpoint +; 1 Global DR0 Breakpoint +; 2 Local DR1 Breakpoint +; 3 Global DR1 Breakpoint +; 4 Local DR2 Breakpoint +; 5 Global DR2 Breakpoint +; 6 Local DR3 Breakpoint +; 7 Global DR3 Breakpoint +; 16-17 Conditions for DR0 +; 18-19 Size of DR0 Breakpoint +; 20-21 Conditions for DR1 +; 22-23 Size of DR1 Breakpoint +; 24-25 Conditions for DR2 +; 26-27 Size of DR2 Breakpoint +; 28-29 Conditions for DR3 +; 30-31 Size of DR3 Breakpoint +; +; A local breakpoint bit deactivates on hardware task switches, while a global does not. +; 00b condition means execution break, 01b means a write watchpoint, and 11b means an R/W watchpoint. +; 10b is reserved for I/O R/W (unsupported). +; +; Test Registers +; Name Description +; TR3 - TR5 Undocumented +; TR6 Test Command Register +; TR7 Test Data Register +; +; Protected Mode Registers +; GDTR +; +; Operand Size Label Description +; 64-bit 32-bit +; Bits 0-15 (Same) Limit Size of GDT +; Bits 16-79 Bits 16-47 Base Starting Address of GDT +; +; LDTR +; Stores the segment selector of the LDT. +; +; TR +; Stores the segment selector of the TSS. +; +; IDTR +; Operand Size Label Description +; 64-bit 32-bit +; Bits 0-15 (Same) Limit Size of IDT +; Bits 16-79 Bits 16-47 Base Starting Address of IDT +;============================================================================================================= +; END OF REGISTER DOCUMENTATION +;============================================================================================================= + +%ifndef AAL_x86_Def +;============================================================================================================= +; Instructions Library +;============================================================================================================= +; NO-Operation : Exchanges value of rax with rax to achieve nothing. +%define nop XCHG rax, rax +;============================================================================================================= +; END - Instructions Library +;============================================================================================================= + +;============================================================================================================= +; Interrupts +;============================================================================================================= +; BIOS + +; CX, DX Interval in microseconds +; CX : High, DX : Low +; SystemService +%define BIOS_Wait 0x86 + +; Disk + +; AL = Number of sectors to read (must be non-zero) +; CH = Track/Cylinder Number +; CL = Sector Number +; DH = Head Number +; DL = Drive Number +; ES:BX = Pointer to Buffer +%define Disk_ReadIntoMemory 0x02 + +; Disk Services (Storage) +%define DiskService 0x13 + +; Memory + +; Real Mode - Conventional Lower Memory +%define Mem_RM_CLower_Start 0x0500 +%define Mem_RM_CLower_End 0x7BFF +; 2 Byte Boundary Alignment +%define Mem_RM_CLower_2BB_End 0x7BE0 + +; Real Mode - Conventional Upper memory +%define Mem_RM_CUpper_Start 0x7E00 +%define Mem_RM_CUpper_End 0x7FFF +; 2 Byte Boundary Alignment +%define Mem_RM_CUpper_2BB_End 0x7FE0 + +; Real Mode - OS Boot Sector +%define Mem_BootSector_Start 0x7C00 +%define Mem_BootSector_512 0x7CFE +%define Mem_BootSector_End 0x7DFF + +; Misc System Services +%define SystemService 0x15 + +; Video +%define VideoService 0x10 + +; Returns +; AH = Number of character columns +; AL = Display mode +; BH = Active Page +%define Video_GetCurrentMode 0x0F + +; Used to set the video mode. +%define Video_SetMode 0x00 + +; SetVideoMode - Modes +; cbOff : Color Burst Off +%define VideoMode_Text_40x25_cbOff 0x00 +%define VideoMode_Text_40x25 0x01 +%define VideoMode_Text_80x25_cbOff 0x02 +%define VideoMode_Text_80x25 0x03 +%define VideoMode_Graphics_320x200 0x04 +%define VideoMode_Graphics_320x200_cboff 0x05 +%define VideoMode_Graphics_640x200 0x06 + +; Output a character +%define Video_TeleType 0xE +; Where memory buffer for Video's Text mode starts +%define Video_Text_MemBuffer 0xB800 +;============================================================================================================= +; END - Interrupts +;============================================================================================================= + + +%define char_CR 0xD ; Carriage Return +%define char_LF 0xA ; Line Feed + + +%define AAL_x86_Def +%endif + + diff --git a/Erus.boot.s b/Erus.boot.s new file mode 100644 index 0000000..84656d6 --- /dev/null +++ b/Erus.boot.s @@ -0,0 +1,79 @@ +; Print HEx + +; x86 +; 16-bit - Real Mode, V86 Mode + +; https://codereview.stackexchange.com/questions/230755/display-hexadecimal-value-stored-at-a-register + + +%include "AAL.x86.s" +%include "AAL.x86.routines.macros.s" + + +; 16-Bit Mode +[BITS 16] +; The ORG directive specifies the starting address of a segment +[ORG Mem_BootSector_Start] + + +start: + mov BX, Mem_BootSector_Start + + mov AH, BIOS_Wait + mov CX, 0x10 +int SystemService + +; Exclusive-OR (xor'ing a value to itself zeros the value) + xor AX, AX +; Set Data Segment and Extra Segment to 0x0000 + mov DS, AX + mov ES, AX +; Set Stack Segment (SS) to to 0x0000 + mov SS, AX +; Set Stack Pointer (SP) to the start of the boot sector. + mov SP, BX + + mov BX, Str_Erus + mov CX, 4 + push CX +call out_string + pop CX + + mov BX, Str_PostMsg + mov CX, 22 + push CX +call out_string + pop CX + + mov AH, BIOS_Wait + mov CX, 0x10 +int SystemService + + mov AH, Video_SetMode + mov AL, VideoMode_Text_80x25 +int VideoService + + mov BX, Str_Erus + mov CX, 4 + push CX +call out_string + pop CX + +; Idle +hang : +jmp short hang + +%include "AAL.x86.routines.s" + +; Data +Str_Erus: db 'Erus' +Str_PostMsg : db '... taking over boot', 0xA, 0xD + +;============================================================================================================= +; Wrap up +;============================================================================================================= +; Byte pad 512 bytes (zeroed) +times 510-$+start db 0 +; Master Boot Record signature +db 0x55 +db 0xAA diff --git a/bare_x86.code-workspace b/bare_x86.code-workspace new file mode 100644 index 0000000..5709732 --- /dev/null +++ b/bare_x86.code-workspace @@ -0,0 +1,8 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": {} +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..2b2ffe2 --- /dev/null +++ b/readme.md @@ -0,0 +1 @@ +Assembly learning dump, nothing special