數據處理的兩個基本問題

定義的描述性符號: reg和sreg,reg表示一個寄存器,用sreg表示一個段寄存器。
reg的集合包括:ax、bx、cx、dx、ah、al、bh、bl、ch、cl、dh、dl、sp、bp、si、di;
sreg的集合包括:ds、ss、cs、es。
bx、si、di和bp
在8086CPU中,只有這4個寄存器可以用在"[...]"中來進行內存單元的尋址。

在[...]中,這4個寄存器可以單個出現,或只能以4種組合出現:bx和si、bx和di、bp和si、bp和di。比如:

只要在[...]中使用寄存器bp,而指令中沒有顯性地給出段地址,段地址就默認在ss中。比如:

機器指令處理的數據在什么地方
絕大部分機器指令都是進行數據處理的指令,處理大致可分為3 類:讀取、寫入、運算。在機器指令這一層來講,並不關心數據的值是多少,而關心指令執行前一刻,它將要處理的數據所在的位置。指令在執行前,所要處理的數據可以在3個地方:CPU內部、內存、端口。

匯編語言中數據位置的表達
存取速度:寄存器 > 1級緩存 > 2級緩存 > 3級緩存 > 內存 > 硬盤。
匯編語言中用3個概念來表達數據的位置。
立即數(idata)
對於直接包含在機器指令中的數據(執行前在CPU的指令緩沖器中),在匯編語言中稱為:立即數(idata),在匯編指令中直接給出。

寄存器
指令要處理的數據在寄存器中,在匯編指令中給出相應的寄存器名。

段地址(SA)和偏移地址(EA)
指令要處理的數據在內存中,在匯編指令中可用[X]的格式給出EA,SA在某個段寄存器中。
ds段地址
存放段地址的寄存器可以是默認的,使用常數、si、di和帶有bx的組合時,段地址默認在ds,例如:

ss段地址
使用bp時,段地址默認在ss中,例如:

顯性給出段地址

尋址方式
當數據存放在內存中的時候,我們可以用多種方式來給定這個內存單元的偏移地址,這種定位內存單元的方法一般被稱為尋址方式。
段地址(Segment Address)
偏移地址(Offset Address)也叫有效地址(EA,Effective Address)

指令要處理的數據有多長
可以處理兩種尺寸的數據,byte和word。所以在機器指令中要指明,指令進行的是字操作還是字節操作。
通過寄存器名指明要處理的數據的尺寸
寄存器指明了指令進行的是字操作,例如:

寄存器指明了指令進行的是字節操作,例如

ptr指明內存單元的長度
在沒有寄存器名存在的情況下,用操作符X ptr指明內存單元的長度, X在匯編指令中可以為word或byte。
用word ptr指明了指令訪問的內存單元是一個字單元,例如:

用byte ptr指明了指令訪問的內存單元是一個字節單元:

在沒有寄存器參與的內存單元訪問指令中,用wordptr或byteptr顯性地指明所要訪問的內存單元的長度是很必要的。否則,CPU無法得知所要訪問的單元是字單元,還是字節單元。
byte ptr

執行后查看結果

word ptr
用e命令修改ds:1000往后的16個字節數據為ff,然后用d查看

查看剛才寫的程序,找到要修改的地方,用a命令修改

修改之后重新查看

用r命令將ip指針重定向到1000:0,然后按t執行

其他方法
有些指令默認了訪問的是字單元還是字節單元,比如,push[1000H]就不用指明訪問的是字單元還是字節單元,因為push指令只進行字操作。
尋址方式的綜合應用

內存中描述

信息變更

匯編實現

C語言實現

C語言對應的匯編


div指令
div是除法指令,使用div做除法的時候應注意以下問題:

格式如下

實例
給出8位被除數,結果存放在同樣8位的al和ah中。


給出16位被除數,結果存放在同樣16位的ax和dx中。


dx高16位需要右移16位,即乘以2^16(十六進制為10000H),在加上低位的ax中存的值即計算出被除數。
利用除法指令計算100001/100
被除數100001大於65535,不能用ax寄存器存放,所以只能用dx和ax兩個寄存器聯合存放100001,也就是說要進行16位的除法。除數100小於255,可以在一個8位寄存器中存放,但是,因為被除數是32位的,除數應為16位,所以要用一個16位寄存器來存放除數100。
100001的十六進制為186A1H,高十六位為1,低十六位為86A1。100的十六進制為64H。

程序執行后,(ax)=03E8H(即1000),(dx)=1(余數為1)。

利用除法指令計算1001/100
被除數1001(3E9H)可用ax寄存器存放,除數100(64H)可用8位寄存器存放,也就是說,要進行8位的除法。

程序執行后,(al)=0AH(即10),(ah)=1(余數為1)。

偽指令dd
前面我們用db和dw定義字節型數據和字型數據。dd是用來定義dword(double word,雙字)型數據的。
data segment db 1 dw 1 dd 1 data ends
在data段中定義了3個數據:
第一個數據為01H,在data:0處,占1個字節;
第二個數據為0001H,在data:l處,占1個字;
第三個數據為00000001H,在data:3處,占2個字。
用div計算data段中第一個數據除以第二個數據后的結果,商存在第三個數據的存儲單元中。

分析:

dup
dup(全稱:duplicate)是一個操作符,在匯編語言中同db、dw、dd等一樣,也是由編譯器識別處理的符號。它是和db、dw、dd等數據定義偽指令配合使用的,用來進行數據的重復。
使用格式

例如:
db 3 dup (0)
定義了3 個字節,它們的值都是0,相當千db 0,0,0 。
db 3 dup (0,1,2)
定義了9個字節,它們是0、l、2、0、1、2、0、1、2,相當千db 0,1,2,0,1,2,0,1,2。
db 3 dup ('abc','ABC')
定義了18個字節,它們是abcABCabcABCabcABC,相當千db ‘abcABCabcABCabcABC’。
定義一個容量為200個字節的棧段
不用dup
用dw聲明100個字,即開辟了200個字節的空間。
stack segment dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 stack ends
使用dup
直接用db聲明200個字節,內容為0。
stack segment db 200 dup (0) stack ends
