register
segment register
CS: Code Segment Register
DS: Data Segment Register
ES: Additional segment register
FS: Additional segment register
GS: Additional segment register
SS: stack segment register
general purpose register
AX: accumulator
BX: base address register
CX: counter
DX: data register
si: source index register
di: destination index register
sp: stack pointer register
bp: base address pointer
flag register
FLAGS
8086-1MB memory distribution
addressing mode
register addressing
immediate addressing
memory addressing
The memory addressing can be divided into:
direct addressing
base addressing
Indexed addressing
base + index addressing
bochs debug commands
Debugger control class
Exit the debug state: q | quit | exit
Set the value of the register: set reg=val
Set whether to disassemble instructions every time you stop execution: set u on | off
Prompt every time you switch modes: show mode
Prompt on every interrupt: show int
Prompt every function call: show call
Print the disassembled code each time an instruction is executed: trace on | off
Code disassembly: u | disasm /num start end
Execution control class
Continue to execute, stop when a breakpoint is encountered: c | cont | continue
Execute n instructions, default 1, do not skip functions: s | step n
Execute 1 instruction, skip function: p|n|next
Breakpoint control class
Set breakpoint by address
Physical address: pb | pbreak | b | break [addr]
Linear address: lb | lbreak [addr]
Virtual address: vb | vbreak [seg : off]
Set a breakpoint by the number of instructions
Interrupt after executing n instructions from the current position: sb n
Interrupt after executing n instructions since the CPU started running: sba n
Set breakpoints with read and write IO
Interrupt when reading [phy_addr]: watch r | read [phy_addr]
Interrupt when writing to [phy_addr]: watch w | write [phy_addr]
Replenish
Show all read and write breakpoints: watch
Clear read-write breakpoint on [phy_addr]: unwatch [phy_addr]
Clear all read and write breakpoints: unwatch
Show all breakpoint information: blist
Disable/enable breakpoint n, n query using blist: bpd | bpe n
Delete breakpoint n, n use blist to query: d | del | delete n
CPU and memory contents class
memory check
View physical address memory: xp /nuf [phy_addr]
View linear address memory: x /nuf [addr]
Stack view: print-stack [num]
n: number of units displayed
u: the size of the display unit, b is 1B, h is 2B, w is 4B, g is 8B
f: display format, x is hexadecimal, d is decimal, u is unsigned decimal, o is octal, t is binary, c is character display, s is ASCIIz display, i is instr display
memory operation
Set the content of consecutive size bytes starting from [phy_addr] to val: setpmem [phy_addr] [size] [val]
Register View
General register view: r | regs | registers
Status register view: info flags | eflags
Segment register view: sreg
Debug register view: dreg
Control register view: creg
View all registers: info CPU
View special data
View breakpoint information, equivalent to blist: info pb | pbreak | b | break
FPU status view: info fpu
View the nth entry in the global descriptor table: info gdt n
View the nth entry in the interrupt vector table: info ivt n
View the interrupt vector table: info idt
View the local descriptor table: info ldt
View the task status section: info tss
View the mapping of linear addresses to physical addresses: page line_addr
View the mapping of linear addresses to physical addresses in the page table: info tab
memory interaction
Basic knowledge of video memory
Memory distribution:
Display Mode:
32KB memory area from start address 0xB8000 to 0xBFFFF for text display
There are many display modes, which are represented by the number of columns and rows, such as 8025, 4025…
The product of the modes is the number of characters that the entire screen can hold, and works in 8025 mode by default
The data structure of 1 character is as follows, the first byte is ASCII code, and the last byte is character attribute
In the working mode of 8025, 1 page screen occupies 280*25 bytes, which can be divided into 32KB/4KB pages in total
Manipulating video memory example
Write the master boot sector code to display Hello, World!!!
Programming mbr.s
;main bootloader ;------------------------------------------------------------ SECTION MBR vstart=0x7c00 mov ax,cs mov ds,ax mov es,ax mov ss,ax mov fs,ax mov ax, 0xB800 mov gs, ax mov sp,0x7c00 ; Clear screen use 0 x06 Number function, scroll up all the lines, you can clear the screen. ; ----------------------------------------------------------- ;INT 0x10 function number:0x06 Function description:roll up window ;------------------------------------------------------ ;enter: ;AH function number= 0x06 ;AL = Number of lines rolled up(if 0,show all) ;BH = Rollup row properties ;(CL,CH) = upper left corner of the window(X,Y)Location ;(DL,DH) = bottom right of the window(X,Y)Location ;No return value: mov ax, 0x600 mov bx, 0x700 mov cx, 0 ; top left: (0, 0) mov dx, 0x184f ; bottom right: (80,25), ; VGA in text mode,A line can only hold 80 characters,25 lines in total. ; subscripts start at 0,so 0 x18=24,0x4f=79 int 0x10 ; int 0x10 ;;;;;;;;; print string ;;;;;;;;;;; mov cx, sx-msg mov si, msg mov di, 0 show_str: mov byte al, [si] mov byte ah, [sx] mov word [gs:di], ax inc si add di, 2 loop show_str ;;;;;;;;; end of typing string ;;;;;;;;;;;;;;; jmp $ ; Hover program here msg db "Hello, World!!!" sx db 0xA4 times 510-($-$$) db 0 db 0x55,0xaa
Compile and write to disk
Compile: nasm -o mbr.bin mbr.s
Write to hard disk: dd if=OS/boot/mbr.bin of=bochs/hd60M.img bs=512 count=1 conv=notrunc
start bochs execution
./bochs installation directory/bin/bochs -f bochs configuration file
Hard disk interaction
Read the loader program from the hard disk through the master boot sector code, and jump to the loader entry for execution
Hard Disk Controller Main Ports
Note: Read and write operations here refer to read and write ports, not hard drives
hard disk addressing
Hard disk structure
CHS mode addressing
Cylinder: Cylinder
Head: magnetic head
Sector: sector
LBA addressing
Divided into LBA28, LBA48
LBA28 addressing:
Bits 0~7: 0x1F3 | 0x173
8~15 bits: 0x1F4 | 0x174
16~23 bits: 0x1F5 | 0x175
24~27 bits: 0x1F6 lower 4 bits | 0x176 lower 4 bits
port
device port
Note: 0 means master disk, 1 means slave disk
command port
Mainly used commands:
identify: 0xEC, hard drive identification
read sector: 0x20, read sector
write sector: 0x30, write sector
status port
Commands for manipulating ports
in op1, op2
in means to read the port register
op1 is a register
op2 is the port number
out op1, op2
out means writing to the port register
op1 is the port number
op2 is a register
Note: op1, op2 can only be dx, ax or al
dx is used to specify the port, ax, al, ah are used to transmit data
Hard disk read and write operation sequence
1. Select the master/slave channel and write the number of sectors to be operated to the sector count port
2. Write the lower 24 bits of the sector logical address, and write the upper 4 bits of the logical sector address into the device
3. Set the 6th bit of the device port to select the addressing mode, and set the 4th bit to select the hard disk
4. Set the command of the command port (read, write or other)
5. Read the status port to get the status of the hard disk, and judge whether the hard disk has completed the work
6. If the above steps are to read the hard disk, go to the next step, otherwise it is completed
7. Read the hard disk data
Replenish:
Whether writing or reading hard disk data, the CPU interacts with the hard disk controller's buffers
When reading data, the hard disk is ready to indicate that the buffer is ready for the required data
When writing data, it is also writing data to the buffer. The hard disk is ready to indicate that the buffer can receive data.
How to read data
1. Unconditional delivery method
2. Query delivery method
3. Interrupt transmission method
4. Direct memory storage method
5. I/O processor transmission mode
Hard Disk Interaction Example
Use the mbr.s program to load the loader.s program in the hard disk, and jump to the loader program to run
The loader program is arranged in the second sector, LBA address: 0x0000001
%include "configuration file name.inc", %include is the preprocessor of nasm, which means that "configuration file name.inc" is included before compilation
Configuration file boot.inc
;--------- mbr & loader --------- LBA_START_SECTOR equ 0x1 SECTOR_COUNT equ 0x1 LOADER_BASE_ADDR equ 0x100 LOADER_OFF_ADDR equ 0x0 LOADER_ADDR equ 0x1000
mbr program
;main bootloader ;------------------------------------------------------------ %include "boot.inc" SECTION MBR vstart=0x7c00 mov ax,cs mov ds,ax mov es,ax mov ss,ax mov fs,ax mov ax, 0xB800 mov gs, ax mov sp,0x7c00 ; Clear screen use 0 x06 Number function, scroll up all the lines, you can clear the screen. ; ----------------------------------------------------------- ;INT 0x10 function number:0x06 Function description:roll up window ;------------------------------------------------------ ;enter: ;AH function number= 0x06 ;AL = Number of lines rolled up(if 0,show all) ;BH = Rollup row properties ;(CL,CH) = upper left corner of the window(X,Y)Location ;(DL,DH) = bottom right of the window(X,Y)Location ;No return value: mov ax, 0x600 mov bx, 0x700 mov cx, 0 ; top left: (0, 0) mov dx, 0x184f ; bottom right: (80,25), ; VGA in text mode,A line can only hold 80 characters,25 lines in total. ; subscripts start at 0,so 0 x18=24,0x4f=79 int 0x10 ; int 0x10 ;;;;;;;;; print string ;;;;;;;;;;; mov cx, sx - msg mov si, msg mov di, 0 show_str: mov byte al, [si] mov byte ah, [sx] mov word [gs:di], ax inc si add di, 2 loop show_str jmp L0 msg db "enter mbr" sx db 0x24 ;;;;;;;;; end of typing string ;;;;;;;;;;;;;;; L0: push ds push di mov eax, LBA_START_SECTOR push eax mov ax, SECTOR_COUNT push ax mov ax, LOADER_BASE_ADDR push ax mov ax, LOADER_OFF_ADDR push ax call read_disk add sp, 10 pop di pop ds jmp LOADER_ADDR ;;;;;;;;; read disk ;;;;;;;;; ; LBA: [bp+10] ; sector count: [bp+8] ; destination: sec=[bp+6], off=[bp+4] read_disk: push bp mov bp, sp ;sector_count mov dx,0x1f2 mov ax, [bp+8] out dx, al ;sector_addr mov dx, 0x1f3 mov ax, [bp+10] out dx, al mov dx, 0x1f4 mov al, ah out dx, al mov dx, 0x1f5 mov ax, [bp+12] out dx, al mov dx, 0x1f6 mov al, ah and al, 0x0f or al, 0xe0 out dx, al ;command_write mov dx, 0x1f7 mov al, 0x20 out dx, al disk_test: nop ;give disk a moment in al, dx and al, 0x88 ;7: BUSY, 3: READY cmp al, 0x08 ; (BUSY=0 & READY=1) or not? jnz disk_test ;data_read: mov ax, [bp+8] mov dx, 256 mul dx mov cx, ax mov bx, [bp+4] mov ax, [bp+6] mov ds, ax mov dx, 0x1f0 go_on_read: in ax, dx mov [bx], ax add bx,2 loop go_on_read mov sp, bp pop bp ret ;;;;;;;;; read disk ;;;;;;;;; times 510-($-$$) db 0 db 0x55,0xaa
loader program
%include "boot.inc" section loader vstart=LOADER_ADDR ;;;;;;;;; print string ;;;;;;;;;;; mov cx, sx-msg mov si, msg mov di, 160 show_str: mov byte al, [si] mov byte ah, [sx] mov word [gs:di], ax inc si add di, 2 loop show_str msg db "enter loader" sx db 0x24 ;;;;;;;;; end of typing string ;;;;;;;;;;;;;;; jmp $
Compile and write to disk
nasm -I The directory where the configuration file is located -o mbr.bin The directory where mbr.s is located/mbr.s
nasm -I The directory where the configuration file is located -o loader.s.bin The directory where loader.s is located/loader.s
dd if=mbr.s directory/mbr.bin of=hard disk directory/hd60M.img bs=512 count=1 seek=0 conv=notrunc
dd if=loader.s directory/loader.bin of=hard disk directory/hd60M.img bs=512 count=1 seek=1 conv=notrunc
start bochs execution
./bochs installation directory/bochs/bin/bochs -f directory where the bochs configuration file is located/boot.disk