x86的寻址方式
段地址 * 16 + 偏移地址
x86实模式下的内存布局
字符显示模式
两个字节显示一个字符
- 第一个字节表示字符
- 第二个字节表示样式
mov byte [0], 'T'
mov byte [1], 11110000b
;显示He
mov byte [0], 'H'
mov byte [2], 'e'
7c00问题
IBM PC 5150 内存布局
寄存器
| 寄存器 | 描述 | | —– | — | | AX | 累加结果数据 | | BX | 数据段数据指针 | | CX | 字符串和循环计数器 | | DX | I/O 指针 | | DI | 目的操作数指针 | | SI | 源操作数指针 | | SP | 栈指针 | | BP | 栈数据指针 |
寄存器 | 高八位 | 低八位 |
---|---|---|
AX | AH | AL |
BX | BH | BL |
CX | CH | CL |
DX | DH | DL |
段寄存器 | 描述 |
---|---|
CS | 代码段寄存器 |
DS | 数据段寄存器 |
SS | 栈段寄存器 |
ES | 额外的寄存器 |
- IP
- FLAG / psw
mov cx, (message_end - message)
loop1:
mov al, [ds:si]
mov [es:di], al
inc si
add di, 2
loop loop1
message:
db "hello world!!!", 0
message_end:
数据类型
db 100; define byte
dw 0xaa55; define word
dd 0x12345678; define double word
dw 55aah
db 1111_0000b
db 0b0000_1111
db "hello world!!!", 0, 12, 123
8086寻址方式
- 立即数的位数
- 默认段寄存器
- 乘法指结果在两个寄存器
标志寄存器
| 位 | 标志 | 英文 | 描述 | | – | — | — | — | | 0 | CF | Cerry | 进位标志 |
转移指令
8086程序的指令地址 cs:ip 下一条指令的地址,物理地址 = cs « 4 + 16
jmp short start 占用两个字节,jmp 偏移地址 -128 - 0x127 jmp neaar start 占用三个地址,-32768 - 32767 改变偏移地址 只能寻64KB内存空间
改变段地址 jmp far cs:ip
cmp ax, bx ; sub ax, bx ——> flag
补码
负数的补码是原码取反再加一 x + 1 = 0 ——> x = -1
0b1111_1111 = -1 0b1111_1110 = -2
0b1111_1011 = -5
堆栈和函数
call faction ——> push ip jmp faction ret ——> pop ip ?? 代返回值的函数?
远调用
call far faction ——> push cs push ip jmp faction retf ——> pop ip pop cs
call 0:print; calf
halt:
jmp halt
print:
push ax
push bx
push es
mov ax, 0xb800
mov es, ax
mov bx, [video]
mov byte [es:bx], '.'
add word [vide0], 2
pop es
pop bx
pop ax
retf
voido:
dw 0x0
内中断和异常
- 远调用
call far [faction]
faction:
dw print, 0; ip, cs
- 内存布局 0x000 - 0x3ff ——> 0x400B 一个中断占4B 0x400 / 4 = 0x100 ——> 256个
0 除法异常 0 - 3 0x80 linux系统调用,软中断 内存位置:(0x80 * 4 — 0x80 * 4 + 3)
- 内中断(软中断) ``` ;注册中断处理函数 mov word [0x80 * 4], faction mov word [0x80 * 4 + 2], 0
;触发中断 int 0x80; push ip; push cs; push flag
halt: jmp halt
print: push ax push bx push es
mov ax, 0xb800 mov es, ax mov bx, [video] mov byte [es:bx], ‘.’ add word [vide0], 2
pop es pop bx pop ax
iret; pop flag; pop cs; pop ip
- 异常
异常与内中断的主要区别是触发机制的不同
;注册中断处理函数 mov word [0x0 * 4], faction mov word [0x0 * 4 + 2], 0
;触发中断 mov dx, 0 mov ax, 1 mov bx, 0 div bx ;dx:ax / bx
## 输入和输出
用输入输出指令,来控制硬件(外围设备)
- 显示器 - 显卡
- 硬盘
- 键盘
端口 - 寄存器(D 边沿触发器) / 映射内存
Intel 0 - 65535 0x0000 ~ 0xffff
CRT 阴极射线管控制器
CRT 地址端口 0x3D4
CRT 数据端口 0x3D5
bochs 80 * 25 = 2000
16位
0 - 1999
0x0E - 光标位置高八位
0x0f - 光标位置低八位
```s
in al, dx; dx 端口号
in ax, dx; ax/al 数
out dx, al
out dx, ax
外中断和时钟
CPU —> 硬件,端口
- 键盘
- 鼠标
flowchart LR 取值 --> 译码 --> 执行 --> 中断
- 时钟信号/脉冲 - CPU 的脉搏
- 时钟中断 - OS 的脉搏
8086 两根线
- NMI Non Maskable Interrupt / 不可屏蔽中断
-
INIR Interrupt / 可屏蔽中断
8259
可编程中断控制器 / PIC Program Interrupt Controller 支持8个可屏蔽中断
- 级联方式
- 主芯片
- 从芯片
flowchart TD subgraph CPU NMI [NMI - 不可屏蔽中断] INIR [INTR - 可屏蔽中断] end subgraph PICM [PIC - 可编程中断控制器 - 主片] CLC [时钟] KB [键盘] SLAVE [级联从片] FLOPPY [软盘] end subgraph PICS [PIC - 可编程中断控制器 - 从盘] RTC [实时时钟] HD [硬盘] MOUSE [鼠标] end PICM --> INTR PICS --> PICM
中断向量表 - 中断函数指针数组
| 向量 | 功能 | | —- | —- | | 0 | 除法益处 | | 1 | 单步(用于调试)| | 2 | 非屏蔽中断 NMI | | 3 | 断点 (用于调试)| | 4 | 溢出中断 | | 5 | 打印屏幕 | | 6 - 7| 保留 | | 8 | 时钟 | | 9 | 键盘 | | A | 保留 | | B | 串行通信COM2 | | C | 串行通信COM1 | | D | 保留 | | E | 软盘控制器 | | F | 并行打印机 |
端口号
| 端口 | 说明 | 标记 | | —- | —- | —- | | 0x20 | 主PIC命令端口 | PIC_M_CMD | | 0x21 | 主PIC数据端口 | PIC_M_DATA | | 0xA0 | 从PIC命令端口 | PIC_S_CMD | | 0xA1 | 从PIC数据端口 | PIC_S_DATA |
寄存器
- ICW1 ~ ICW4 用于初始化 8259 initialization Command Words
- OCW1 ~ OCW3 用于操作 8259 Operation Commands Words
- 注册中断函数
- 向 OCW1 写入屏蔽字,打开时钟中断
- sti 设置状态字 CPU 允许外中断
- 向 OCW2 写入 0x20, 表示中段处理完毕,可接受下次中断
中断处理函数执行栈区变化
; 状态字 0x206 - 0b0010_0000_0110
clock:
; push flags
; push cs
; push ip
; xchg bx, bx ; 方便调试,查看栈区变化
硬盘读写
PC 的状态
- 加电
- BIOS
- 主引导扇区 –> 0x7c00 (主引导扇区加载到内存0x7c00处)
- 跳转到 –> 0x7c00
- 主引导扇区只有 512 个字节 / 包括硬盘分区信息,55aa
读取协议
- IDE Integrated Drive Electronics
- ATA Advanced Technology Attachment
读取方式
- CHS 模式 - Cylinder / Head / Sector
- LBA 模式 - Logical Block Address
硬盘操作端口
Primary 通道 | Secondary 通道 | in 操作 | out 操作 |
---|---|---|---|
Command Block Registers | |||
0x1F0 | 0x170 | Data | Data |
0x1F1 | 0x171 | Error | Features |
0x1F2 | 0x172 | Sector count | Sector count |
0x1F3 | 0x173 | LBA low | LBA low |
0x1F4 | 0x174 | LBA mid | LBA mid |
0x1F5 | 0x175 | LBA high | LBA high |
0x1F6 | 0x176 | Device | Device |
0x1F7 | 0x177 | Status | Command |
- 0x1F0 / 16bit 读写数据
- 0x1F1
- 0x1F2 / 8bit 读写扇区数量
- 0x1F3 - 0x1F5 / 起始扇区的前 24 位 0 ~ 23 位
- 0x1F6
- 0 - 3 / LBA 24 ~ 27位
- 4:0 主盘, 1 从盘
- 6:0 CHS 模式, 1 LBA
- 5 7: 固定为 1
- 0x1F7: out
- 0xEC: 识别硬盘
- 0x20: 读硬盘
- 0x30: 写硬盘 in
- 0: ERR
- 3: DRQ 数据准备完毕
- 7: