?? o語(yǔ)言匯編基礎(chǔ)教程.htm
字號(hào):
<TD WIDTH="36%" VALIGN="TOP" HEIGHT=50>
寄存器/內(nèi)存寄存器<br>
jjj/nnn</TD>
<TD WIDTH="30%" VALIGN="TOP" HEIGHT=50>
內(nèi)存位移量<br>
disp</TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
2位</TD>
<TD WIDTH="20%" VALIGN="TOP">
3位</TD>
<TD WIDTH="36%" VALIGN="TOP">
3位</TD>
<TD WIDTH="30%" VALIGN="TOP">
8位/16|32位</TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
11</TD>
<TD WIDTH="20%" VALIGN="TOP">
寄存器</TD>
<TD WIDTH="36%" VALIGN="TOP">
寄存器</TD>
<TD WIDTH="30%" VALIGN="TOP">
無(wú)</TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
00</TD>
<TD WIDTH="20%" VALIGN="TOP">
寄存器</TD>
<TD WIDTH="36%" VALIGN="TOP">
內(nèi)存寄存器</TD>
<TD WIDTH="30%" VALIGN="TOP">
無(wú)</TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
01</TD>
<TD WIDTH="20%" VALIGN="TOP">
寄存器</TD>
<TD WIDTH="36%" VALIGN="TOP">
內(nèi)存寄存器</TD>
<TD WIDTH="30%" VALIGN="TOP">
8位位移量</TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
10</TD>
<TD WIDTH="20%" VALIGN="TOP">
寄存器</TD>
<TD WIDTH="36%" VALIGN="TOP">
內(nèi)存寄存器</TD>
<TD WIDTH="30%" VALIGN="TOP">
16位模式:16位位移量<br>
32位模式:32位位移量</TD>
</TR>
<TR><TD WIDTH="15%" VALIGN="TOP">
備注</TD>
<TD WIDTH="85%" VALIGN="TOP" COLSPAN=3>
如果寄存器域被預(yù)設(shè)固定值則只取寄存器/內(nèi)存寄存器域的值<br>
此時(shí)變化成為要么只有一個(gè)寄存器要么只有內(nèi)存內(nèi)存尋址的情況</TD>
</TR>
</TABLE><br>
(表2.2 寄存器字節(jié)分析)<br>
有三個(gè)操作數(shù)的指令又是如何的呢?實(shí)事上搞明白了上一種變化,三個(gè)操作數(shù)就很容易了,它只不過(guò)是在兩個(gè)寄存器或內(nèi)存地址操作數(shù)之后再加一個(gè)立即數(shù),這種情況同樣有一種特例,那就是有兩個(gè)相同寄存器操作數(shù),和一個(gè)立即數(shù),那么在寫(xiě)匯編代碼的時(shí)候就把這種情況認(rèn)為是一個(gè)寄存器和一個(gè)立即數(shù),而實(shí)際翻譯成二進(jìn)制代碼時(shí)要翻譯成兩個(gè)相同的寄存器和一個(gè)立即數(shù),它同樣是屬于三個(gè)操作數(shù)的情況,符號(hào)乘法(IMUL)指令就屬于這一種特例。<br>
在具體的指令中還有一些例外,比如,一個(gè)看上去只有一個(gè)操作碼,不含操作數(shù)的指令,而實(shí)際上它有隱含的寄存器作為它的操作數(shù)如計(jì)數(shù)寄存器,或者它的寄存器操作數(shù)被指令指定了,而不是可變的,如只使用累加寄存器。比如下例指令:1010 0001 0000 0000 0000 0000 0001 0010 0011 0100,用十六進(jìn)制表示是0xA100001234,它的操作碼是開(kāi)始字節(jié)1010 0001,操作碼的倒數(shù)第二位0指示操作數(shù)流向,最后一位1指示操作數(shù)大小,這串二進(jìn)制碼指令不含有寄存器,但實(shí)際上由它的操作碼決定了它隱含有累加寄存器。這串指令的實(shí)際意義是將位于內(nèi)存地址0x00001234處的32位數(shù)據(jù)傳送到累加三二寄存器中。請(qǐng)注意這里的方向位,它與前面講述的有所不同,通常情況,當(dāng)方向位為0時(shí),操作數(shù)流向中從左到右,即寄存器=>內(nèi)存地址,而方向位為1是從右到左,即寄存器<=內(nèi)存地址,但這是由于沒(méi)有顯示是給出寄存器,所以它的方向與之相反,也就是為0時(shí)它是寄存器<=內(nèi)存地址,為1時(shí)它是寄存器=>內(nèi)存地址。<br>
三、內(nèi)存尋址 指令共存在三種操作數(shù):寄存器操作數(shù)、內(nèi)存操作數(shù)和立即數(shù)操作數(shù)。由前面分析我們知道,指令是通過(guò)一個(gè)叫做模數(shù)(MOD)的兩位二進(jìn)制位來(lái)指定寄存器操作數(shù)字節(jié)的最后三位代表的意義。因此,一條指令最多只可能有兩個(gè)寄存器操作數(shù)(MOD=11);最多只可能有一個(gè)內(nèi)存操作數(shù)(MOD=00/01/10),永遠(yuǎn)也不可能出現(xiàn)兩個(gè)或者兩個(gè)以上內(nèi)存操作數(shù)的情況,而且也只可能有一個(gè)立即數(shù)操作數(shù)。有幾個(gè)很特殊的指令擁有隱含的寄存器作為操作數(shù),隱含寄存器通常是累加寄存器或者計(jì)數(shù)寄存器,隱含寄存器不由模數(shù)來(lái)決定而是由操作碼來(lái)決定,因此,在極少的情況下有可能出現(xiàn)三個(gè)寄存器操作數(shù)的情況,如:監(jiān)視指令,指令英文名稱是MONITOR,它就擁有累加三二、計(jì)數(shù)三二和數(shù)據(jù)三二三個(gè)寄存器操作數(shù)。<br>
內(nèi)存操作數(shù)相當(dāng)復(fù)雜,這不僅是因?yàn)橛赡?shù)決定是否擁有內(nèi)存位移量的情況,更主要的是因?yàn)橛扇欢M(jìn)制數(shù)來(lái)表示內(nèi)存操作數(shù)時(shí)變化繁多。三位二進(jìn)制數(shù)排序可以有八種變化,它們分別是000、001、010、011、100、101、110、111,這就代表八種不同的尋址方式。下面是在16位模式下這八個(gè)數(shù)分別代表的意義:<br>
<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=539>
<TR><TD WIDTH="21%" VALIGN="TOP">
內(nèi)存二進(jìn)制碼</TD>
<TD WIDTH="47%" VALIGN="TOP">
尋址方式中文表示</TD>
<TD WIDTH="32%" VALIGN="TOP">
尋址方式英文表示</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
000</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[基址一六 +源變址一六 ]</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
DS:[BX+SI]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
001</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[基址一六 +目的變址一六]</TD>
<TD WIDTH="32%" VALIGN="TOP">
DS:[BX+DI]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
010</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
堆棧段:[基址指針一六+源變址一六 ]</TD>
<TD WIDTH="32%" VALIGN="TOP">
SS:[BP+SI]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
011</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
堆棧段:[基址指針一六+目的變址一六]</TD>
<TD WIDTH="32%" VALIGN="TOP">
SS:[BP+DI]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
100</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[源變址一六 ]</TD>
<TD WIDTH="32%" VALIGN="TOP">
DS:[SI]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
101</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[目的變址一六]</TD>
<TD WIDTH="32%" VALIGN="TOP">
DS:[DI]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
110</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
堆棧段:[基址指針一六]*</TD>
<TD WIDTH="32%" VALIGN="TOP">
SS:[BP]*</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
111</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[基址一六 ]</TD>
<TD WIDTH="32%" VALIGN="TOP">
DS:[BX]</TD>
</TR>
</TABLE><br>
(表2.3 16位內(nèi)存尋址方式)<br><br>
下面解釋一下這幾種情況:前四種情況即內(nèi)存二進(jìn)制碼為000、001、010和011時(shí),尋址方式叫做<B>基址加變址尋址</B>,如果內(nèi)存寄存器中含有基址指針寄存器則訪問(wèn)的是堆棧段內(nèi)的數(shù)據(jù)(下面的情況也如此),否則訪問(wèn)的是數(shù)據(jù)段內(nèi)的數(shù)據(jù),它的實(shí)際內(nèi)存地址是相對(duì)于數(shù)據(jù)段寄存器或者是堆棧段寄存器表示的數(shù)據(jù)段首地址加上后面兩個(gè)寄存器值。后四種情況即內(nèi)存二進(jìn)制碼為100、101、110和111時(shí),尋址方式稱為<B>寄存器間接尋址</B>,為什么不叫做寄存器尋址,而是間接尋址呢?在相關(guān)的書(shū)籍中,把寄存器操作數(shù)和立即數(shù)操作數(shù)都納入尋址概念的范圍,因此把寄存器操作數(shù)叫做<B>寄存器尋址</B>,把立即數(shù)操作數(shù)叫做<B>立即尋址</B>,而內(nèi)存寄存器尋址只好稱為間接尋址了。我個(gè)人認(rèn)為,把內(nèi)存操作數(shù)與寄存器和立即數(shù)操作數(shù)分開(kāi),更容易理解,寄存器與立即數(shù)很簡(jiǎn)單,而內(nèi)存操作數(shù)則變化復(fù)雜,掌握了指令操作數(shù)的模型很容易區(qū)分各種操作數(shù)的情況。后四種情況與前四種不同的就是只含有一個(gè)內(nèi)存寄存器,實(shí)際內(nèi)存地址少加了源變址或者目的變址寄存器的值。試想一下,上面所有列出的情況,內(nèi)存尋址時(shí)都至少需要加上一個(gè)寄存器的值,如果我們直接給出內(nèi)存相對(duì)于段首地址的位移量,而不需要加某個(gè)寄存器的值,難道就不能訪問(wèn)內(nèi)存了嗎?這當(dāng)然是不符合現(xiàn)實(shí)情況的,細(xì)心的你一定發(fā)現(xiàn)了在表2.3的倒數(shù)第二行,即內(nèi)存二進(jìn)制碼為110時(shí)尋址方式用了星號(hào)(*)注示,這種特殊的尋址方式就是用這一行的格式來(lái)表示的。當(dāng)內(nèi)存操作數(shù)不含寄存器只含有位移量時(shí),把這種尋址方式稱為<B>直接尋址</B>,此時(shí),內(nèi)存寄存器的三位二進(jìn)制數(shù)被設(shè)置成基址指針寄存器,則模數(shù)被設(shè)置在00,即MOD=00、nnn=110。但是按照前面的分析,當(dāng)模數(shù)MOD=00時(shí)表示的是內(nèi)存寄存器沒(méi)有位移量的情況,這就產(chǎn)生了沖突,于是就取消了內(nèi)存寄存器為基址指針即nnn=110時(shí)沒(méi)有位移量的表示情況,換句話說(shuō),如果你的意圖是要表示當(dāng)內(nèi)存寄存器為基址指針且沒(méi)有位移量的情況時(shí),就必須表示成有8位位移量或者有16位位移量,且設(shè)置位移量為0的情況,即必須按下面的方法表示:MOD=01、disp=0x00或者M(jìn)OD=10、disp=0x0000,來(lái)達(dá)到同樣的目的。僅僅是內(nèi)存寄存器就有這8種加1種特殊的尋址,共9種尋址的方式,如果再加上8位和16位的位移量,可想而知內(nèi)存操作數(shù)是多么的復(fù)雜。有一點(diǎn)不要忘了,內(nèi)存寄存器只表示一個(gè)內(nèi)存地址,它真正的操作數(shù)是保存在內(nèi)存地址指向的內(nèi)存空間中的數(shù)據(jù)。如果有兩個(gè)操作數(shù),其中一個(gè)是寄存器操作數(shù),而另一個(gè)是內(nèi)存操作數(shù),按照操作數(shù)大小匹配的原則,內(nèi)存空間的大小與寄存器的大小保持一致,如果是8位寄存器操作數(shù),那么內(nèi)存操作數(shù)也是8位,是16位寄存器操作數(shù),則內(nèi)存操作數(shù)也是16位,但是如果只有一個(gè)內(nèi)存操作數(shù),或者有兩個(gè)操作數(shù),其中一個(gè)是內(nèi)存操作數(shù),而另一個(gè)是立即數(shù)操作數(shù),那如何來(lái)確定內(nèi)存操作數(shù)的大小呢?這就由必須由操作碼來(lái)區(qū)分內(nèi)存操作數(shù)的大小,這就是為什么有些操作碼的最后一位用來(lái)指示是8位還是16位(在32位模式下是32位)內(nèi)存操作數(shù)的大小。下面列出了16位尋址可能的組合:<br><br>
16位尋址方式時(shí)模數(shù)mm與內(nèi)存尋址nnn可能的組合<br>
mm nnn 尋址方式中文表示 尋址方式英文表示<br>
00 000 數(shù)據(jù)段:[基址一六+源變址一六] DS:[BX+SI]<br>
00 001 數(shù)據(jù)段:[基址一六+目標(biāo)變址一六] DS:[BX+DI]<br>
00 010 堆棧段:[基址指針一六+源變址一六] SS:[BP+SI]<br>
00 011 堆棧段:[基址指針一六+目標(biāo)變址一六] SS:[BP+DI]<br>
00 100 數(shù)據(jù)段:[源變址一六] DS:[SI]<br>
00 101 數(shù)據(jù)段:[目標(biāo)變址一六] DS:[DI]<br>
00 110 堆棧段:[基址指針一六] SS:[BP]<br>
00 111 數(shù)據(jù)段:[基址一六] DS:[BX]<br>
01 000 數(shù)據(jù)段:[基址一六+源變址一六+8位符號(hào)位移] DS:[BX+SI+sign_disp8]<br>
01 001 數(shù)據(jù)段:[基址一六+目標(biāo)變址一六+8位符號(hào)位移] DS:[BX+DI+sign_disp8]<br>
01 010 堆棧段:[基址指針一六+源變址一六+8位符號(hào)位移] SS:[BP+SI+sign_disp8]<br>
01 011 堆棧段:[基址指針一六+目標(biāo)變址一六+8位符號(hào)位移] SS:[BP+DI+sign_disp8]<br>
01 100 數(shù)據(jù)段:[源變址一六+8位符號(hào)位移] DS:[SI+sign_disp8]<br>
01 101 數(shù)據(jù)段:[目標(biāo)變址一六+8位符號(hào)位移] DS:[DI+sign_disp8]<br>
01 110 堆棧段:[基址指針一六+8位符號(hào)位移] SS:[BP+sign_disp8]<br>
01 111 數(shù)據(jù)段:[基址一六+8位符號(hào)位移] DS:[BX+sign_disp8]<br>
10 000 數(shù)據(jù)段:[基址一六+源變址一六+16位符號(hào)位移] DS:[BX+SI+disp16]<br>
10 001 數(shù)據(jù)段:[基址一六+目標(biāo)變址一六+16位符號(hào)位移] DS:[BX+DI+disp16]<br>
10 010 堆棧段:[基址指針一六+源變址一六+16位符號(hào)位移] SS:[BP+SI+disp16]<br>
10 011 堆棧段:[基址指針一六+目標(biāo)變址一六+16位符號(hào)位移] SS:[BP+DI+disp16]<br>
10 100 數(shù)據(jù)段:[源變址一六+16位符號(hào)位移] DS:[SI+disp16]<br>
10 101 數(shù)據(jù)段:[目標(biāo)變址一六+16位符號(hào)位移] DS:[DI+disp16]<br>
10 110 堆棧段:[基址指針一六+16位符號(hào)位移] SS:[BP+disp16]<br>
10 111 數(shù)據(jù)段:[基址一六+16位符號(hào)位移] DS:[BX+disp16]<br>
(表2.4 16位內(nèi)存尋址方式組合)<br>
386或更高的處理器使用的是32位的尋址方式,它要比上述16位尋址方式還要復(fù)雜得多,原因是在32位尋址方式下引用了比例尋址。下表2.5列出了32位的尋址方式:<br>
<TABLE BORDER CELLSPACING=1 CELLPADDING=7 WIDTH=539>
<TR><TD WIDTH="21%" VALIGN="TOP">
內(nèi)存二進(jìn)制碼</TD>
<TD WIDTH="47%" VALIGN="TOP">
尋址方式中文表示</TD>
<TD WIDTH="32%" VALIGN="TOP">
尋址方式英文表示</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
000</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[累加三二]</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
DS:[EAX]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
001</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[計(jì)數(shù)三二]</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
DS:[ECX]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
010</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[數(shù)據(jù)三二]</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
DS:[EDX]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
011</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[基址三二]</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
DS:[EBX]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
100</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
使用比例變址字節(jié)</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
使用比例變址字節(jié)</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
101</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
堆棧段:[基址指針三二]*</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
SS:[EBP]*</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
110</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[源變址三二]</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
DS:[ESI]</TD>
</TR>
<TR><TD WIDTH="21%" VALIGN="MIDDLE">
111</TD>
<TD WIDTH="47%" VALIGN="MIDDLE">
數(shù)據(jù)段:[目的變址三二]</TD>
<TD WIDTH="32%" VALIGN="MIDDLE">
DS:[EDI]</TD>
</TR>
</TABLE><br>
(表2.5 32位內(nèi)存尋址方式)<br>
32位尋址與16位尋址原理相同,都是利用指定的寄存器表示位移量來(lái)訪問(wèn)相對(duì)于段首地址的相應(yīng)段內(nèi)存地址數(shù)據(jù)。如果內(nèi)存寄存器是基址指針寄存器則訪問(wèn)的是堆棧段數(shù)據(jù),否則訪問(wèn)的是數(shù)據(jù)段的數(shù)據(jù)。請(qǐng)?zhí)貏e注意使用比例變址字節(jié)及打星號(hào)(*)的兩項(xiàng),打星號(hào)的是表示特殊尋址,與16位尋址相同,但16位的內(nèi)存二進(jìn)制碼是nnn=110而32位是nnn=101,特殊尋址的特殊之處就在于取消了MOD=00沒(méi)有位移量的內(nèi)存表示方式而取代為<B>直接尋址</B>,將沒(méi)有位移量的情況表示成8位位移量或者32位位移量為0的情況,即用MOD=01、disp=0x00或者M(jìn)OD=10、disp=0x00000000來(lái)表示。使用比例變址字節(jié)是什么意思呢?意思就是當(dāng)內(nèi)存二進(jìn)制碼為100即nnn=100時(shí),在當(dāng)前內(nèi)存寄存器字節(jié)之后再加一個(gè)字節(jié)來(lái)表示內(nèi)存。我們把這個(gè)增加的字節(jié)稱為比例變址字節(jié),用比例變址字節(jié)來(lái)表示內(nèi)存地址的方式我們稱之為<B>比例變址尋址</B>。用比例變址字節(jié)來(lái)表示內(nèi)存時(shí)可以用比例的方式來(lái)表示內(nèi)存地址,具體的表示方法如下。一個(gè)字節(jié)是8位二進(jìn)制數(shù),取字節(jié)的頭兩位作為比例因子,兩位二進(jìn)制數(shù)可以表示四個(gè)數(shù),相應(yīng)地就有四個(gè)比例因子,兩位比例因子用ss表示就是ss=00時(shí)因子為1、ss=01時(shí)因子為2、ss=10時(shí)因子為4、ss=11時(shí)因子為8。再取字節(jié)的后三位來(lái)表示變址域寄存器,也就是這三位表示的寄存器的值要乘以前面的因子,最后三位表示基址域寄存器,也就是最后要加這三位表示寄存器的值才能最終得到指定內(nèi)存的地址。舉一個(gè)簡(jiǎn)單的例子,比如比例變址字節(jié)的值為10010001,它的ss=10則比例因子為4,010是數(shù)據(jù)三二寄存器,001是計(jì)數(shù)三二寄存器,則最后內(nèi)存地址就是[4*數(shù)據(jù)三二+計(jì)數(shù)三二],內(nèi)存地址用中括號(hào)來(lái)表示,由于變址域寄存器和基址域寄存器都可以用不同的寄存器來(lái)表示,加上不同的因子、8位位移量以及32位位移量的
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -