前言
- x86
x86的起點是Intel 8086處理器
8086是16位處理器
一個字節八位
- 寄存器
14個寄存器
AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES
八個通用寄存器
AX,BX,CX,DX,SP,BP,SI,DI
通用寄存器
數據寄存器
數據寄存器AX,BX,CX,DX
AX (Accumulator):累加寄存器,也稱之為累加器;
BX (Base):基地址寄存器;
CX (Count):計數器寄存器;
DX (Data):數據寄存器;
指針寄存器SP,BP
SP (Stack Pointer):堆棧指針寄存器;
BP (Base Pointer):基指針寄存器;
變址寄存器SI,DI
SI (Source Index):源變址寄存器;
DI (Destination Index):目的變址寄存器
控制寄存器
IP (Instruction Pointer):指令指針寄存器;
FLAG:標志寄存器;
段寄存器
CS (Code Segment):代碼段寄存器;
DS (Data Segment):數據段寄存器;
SS (Stack Segment):堆棧段寄存器;
ES (Extra Segment):附加段寄存器
AX可以拆分兩個寄存器,高八位AH,低八位AL
AX=AH,AL BX=BH,BL CX=CH,CL DX=DH,DL
- 8086有20根地址線,尋址范圍2的20次方,等於1MB,轉成16進制為0x00000-0xfffff
16位數值范圍
進制 | 范圍 | 數值 | 備注 |
---|---|---|---|
二進制 | 0000 0000 0000 0000 - 1111 1111 1111 1111 | ||
十六進制 | 0000 - FFFF | 十六進制一位表示二進制四位 | |
十進制 | 0 - 65535 | 65536 = 64KB |
20位總線尋址范圍
進制 | 范圍 | 數值 | 備注 |
---|---|---|---|
二進制 | 0000 0000 0000 0000 0000 - 1111 1111 1111 1111 1111 | 根據上面來說在加四位 | |
十六進制 | 00000 - FFFFF | ||
十進制 | 0 - 1048575 | 1048576 = 1MB |
- FAQ:寄存器是16位,但是數據總線是20位,那16位寄存器如何使用20位地址總線,並尋址到1MB呢?
16位實模式下,寄存器需要段地址結合偏移地址來讓尋址1MB,使用兩個寄存器來出來,段寄存器,偏移寄存器
物理地址=段地址*16(段地址<<4) + 偏移地址
段的意思是1MB分16個64KB的段
在通過偏移地址尋址64KB,0x0000-0xffff就是偏移地址的范圍
舉個例子
段地址0xffff,偏移地址0xffff,物理地址等於多少?
0x1000 << 4(0x10000*16) = 0x10000
0x1000 + 0xffff = 1ffff < 0xfffff是有效物理內存地址
如果段0xffff << 4 + 0xffff = 0x10ffef > 0xfffff 無效地址,在8026中是一個異常,並且執行0x00000處
參考:
http://www.cppblog.com/mydriverc/articles/30719.html
- 1MB尋址范圍分配
CPU尋址范圍內的地址分配給其他設備
地址范圍 | 大小 | 分配對象 | 細分 |
---|---|---|---|
0x00000-0x9ffff | 640KB | 內存 | 0x07c00-ox07DFF 512B為BootLoader |
0xaffff-0xBFFFF | 128KB | 文字圖像 | 0xA0000-0xAFFFF 64KB EGA/VGA/XGA/XVGA彩色模式 0xb0000-0xb7fff 32KB 黑白文本 0xB80000-0xBffff 32KB 為彩色文本 這些地址映射為顯卡顯存,寫入相當於寫入顯存 |
0xCFFFF-0xFFFFF | 256KB | BIOS |
安裝相應的軟件
- 安裝Vscode編輯器,並安裝打開二進制文件的插件
Hex editer
- 安裝Nasm,nasm-2.15.05-installer-x64.exe,記得加入環境變量
- 安裝virtualbox,VirtualBox-6.1.22-144080-Win.exe
- FixVhdw 把文件寫入硬盤
- WinHex 讀取寫入裸盤,把程序寫入U盤
軟件打包下載地址,鏈接: https://pan.baidu.com/s/1YN7mB5uPuIzcacS-Q-YCmg 提取碼: 5ua2
開發一段測試代碼
第一個匯編程序start.asm
mov ax, 0b800h # 顯卡彩色文字模式起始位
mov ds,ax
mov byte [0x00],'2'
mov byte [0x02],'0'
mov byte [0x04],'2'
mov byte [0x06],'1'
mov byte [0x08],','
mov byte [0x0a],'H'
mov byte [0x0c],'a'
mov byte [0x0e],'p'
mov byte [0x10],'p'
mov byte [0x12],'y'
mov byte [0x14],' '
mov byte [0x16],'N'
mov byte [0x18],'i'
mov byte [0x1a],'u'
mov byte [0x1c],' '
mov byte [0x1e],'Y'
mov byte [0x20],'e'
mov byte [0x22],'a'
mov byte [0x24],'r'
mov byte [0x26],'!'
jmp $ #
times 510-($-$$) db 0 # 補0,$$起始位置,$表示jmp所在位置,$-$$從開頭到jmp一共多少個字節,512減去兩個標志位55 aa得到510,510減去($-$$)中間填充0
db 0x55,0xaa # MBR分區最后的標志位
使用Nasm編譯為二進制文件,生成start.bin
nasm -f bin start.asm -o start.bin
然后新建other類型dos版本的虛擬機
- 硬盤類型vhd
- 固定硬盤16MB
- 其余選項默認
使用FixVhdw把程序寫入硬盤
- 選擇虛擬硬盤Vhd文件
- 數據文件選擇1為start.bin文件
- 起始LBA扇區號為0
- 寫入
軟件寫入U盤真機運行
- u盤使用fet32格式
- 打開WinHex,然后tool-> open disk -> 選擇U盤(physical storages devices,不要選擇logical)
- file-> open file -> 打開start.bin文件,
- 在start.bin標簽頁,選擇所有的0之前的數據,不是全部數據,點擊Copy All小圖標
- 在u盤標簽頁,點擊write clipboard小圖標,寫入最上面的數據,后面的數據不能破壞!
- 在u盤標簽頁,點擊save小圖標