本節將學習16bit模式的段結構關鍵字:段目標:學習如何在16bit模式下定址如果你對段已經很熟悉了,那麼你可以跳過本節.
在從0建立乙個os (四) 電腦儲存的組織形式一節中我們利用org完成了對booot sector的全域性基址定義,那是我們第一次在本系列部落格中接觸到段的概念.
段暫存器中儲存的為段位址,從第一代8086機問世以來,之後每一代計算機的基礎段暫存器一直沒有變化,有以下4個:
cs: code segment **段ds: data segment 資料段ss: stack segment 棧段es: extented segment 擴充套件段其中ds常和es搭配使用,用於複製字串.
這4個暫存器無法直接使用類似於mov cs, 0xcd的語句賦值,必須借助於中間暫存器,如:
mov ax, 0xcd
mov cs, ax
注意!這4個暫存器在隱式地被cpu呼叫,用來定址,所以在改變這4個暫存器的值之前,你必須明白自己在做什麼,會不會影響到cpu接下來的定址.16bit模式下的實體地址計算方法如下:
物 理地
址=段地
址<
<4+
偏移位址
實體地址 = 段位址 << 4 + 偏移位址
實體地址=段
位址<
<4+
偏移位址
例如,假設當前的ds的值為0x4d,那麼[x20]表示的實體地址為:
0x4d0 + 0x20 = 0x4f0
至於為什麼要將段位址左移4位呢?本文不做解釋,可以給大家提供乙個線索,第一代8086的資料匯流排有20位.
廢話不多說,上**
注意,這次我們並沒有使用[org 0x7c00]
檔名: boot_sect_segmentation.asm
;
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
=; 本程式做了4個嘗試
;1、直接列印標籤the_secret指向的值
;2、對段暫存器ds賦值0x7c0
,隱式呼叫ds,並列印the_secret指向的值
;3、直接顯式呼叫段暫存器es,看看能否使用[es:the_secret]完成對the_secret的列印
;4、對段暫存器es賦值0x7c0
,顯式呼叫es,並列印the_secret指向的值;==
====
====
====
====
====
====
====
====
====
====
====
====
====
====
====
*****==
mov ah,
0x0e
; 準備使用0x10號中斷的列印字元功能
mov al,
[the_secret]
int0x10
; 很明顯這樣是列印不出來東西的,本系列部落格的第二節就嘗試過了
; 給資料段段暫存器賦值,0x7c0
,是不是很眼熟?
mov bx,
0x7c0
mov ds, bx
; 這裡的[the_secret]其實是[ds:the_secret]
mov al,
[the_secret]
int0x10
; 顯式呼叫es作為the_secret的段位址儲存器
mov al,
[es:the_secret]
int0x10
; 向es賦上我們熟悉的值0x7c0
發現嘗試2和嘗試4列印成功,即隱式呼叫ds和顯式呼叫es成功,說明cpu在定址時預設使用的段暫存器為ds.
從ACM中刪除乙個已經建立的Library
從acm中刪除乙個已經建立的library,無法通過介面操作,須要手工從db中刪除。須要刪除的表記錄有 recentupdate 找到欄位name等於該libraryname的那條記錄刪除掉 delete from recentupdate where name techair containert...
彙編實現乙個0到9的整數輸入
data segment num byte inputstr db please input a positive number 定義提示輸入的字串 outstr db your input is 定義輸出的字串 errostr db erro input 定義錯誤的字串 crlf db 0ah,0...
乙個完整的Windows 服務從建立到安裝解除安裝
第 一 建立乙個windows服務 第二 在自動生成的program類中寫你要寫的 using system using system.collections.generic using system.linq using system.serviceprocess using system.tex...