X86 匯編環境搭建並運行第一個程序


前言

  • 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

image

安裝相應的軟件

  1. 安裝Vscode編輯器,並安裝打開二進制文件的插件Hex editer
  2. 安裝Nasmnasm-2.15.05-installer-x64.exe,記得加入環境變量
  3. 安裝virtualboxVirtualBox-6.1.22-144080-Win.exe
  4. FixVhdw 把文件寫入硬盤
  5. 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版本的虛擬機

  1. 硬盤類型vhd
  2. 固定硬盤16MB
  3. 其余選項默認

使用FixVhdw把程序寫入硬盤

  1. 選擇虛擬硬盤Vhd文件
  2. 數據文件選擇1為start.bin文件
  3. 起始LBA扇區號為0
  4. 寫入

軟件寫入U盤真機運行

  1. u盤使用fet32格式
  2. 打開WinHex,然后tool-> open disk -> 選擇U盤(physical storages devices,不要選擇logical)
  3. file-> open file -> 打開start.bin文件,
  4. 在start.bin標簽頁,選擇所有的0之前的數據,不是全部數據,點擊Copy All小圖標
  5. 在u盤標簽頁,點擊write clipboard小圖標,寫入最上面的數據,后面的數據不能破壞!
  6. 在u盤標簽頁,點擊save小圖標

讓顯卡顯示內容


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM