單片機(jī)匯編指令入門(mén)學(xué)習(xí)和查看
51的匯編控制指令詳細(xì)列表
8051 INSTRUCTION SET
1.Arithmetic operations:
Mnemonic Byte Cyc
ADD A,@Ri 1 1
ADD A,Rn 1 1
ADD A,direct 2 1
ADD A,#data 2 1
ADDC A,@Ri 1 1
ADDC A,Rn 1 1
ADDC A,direct 2 1
ADDC A,#data 2 1
SUBB A,@Ri 1 1
SUBB A,Rn 1 1
SUBB A,direct 2 1
SUBB A,#data 2 1
INC A 1 1
INC @Ri 1 1
INC Rn 1 1
INC DPTR 1 1
INC direct 2 1
INC direct 2 1
DEC A 1 1
DEC @Ri 1 1
DEC Rn 1 1
DEC direct 2 1
MUL AB 1 4
DIV AB 1 4
DA A 1 1
8051的匯編控制指令,占用字節(jié),執(zhí)行周期列表
3.Data transfer:
Mnemonic Byte Cyc
MOV A,@Ri 1 1
MOV DPTR,#data16 3 2
MOV A,Rn 1 1
MOVC A,@A+DPTR 1 2
MOV A,direct 2 1
MOVC A,@A+PC 1 2
MOV A,#data 2 1
MOVX A,@Ri 1 2
MOV @Ri,A 1 1
MOVX A,@DPTR 1 2
MOV @Ri,direct 2 2
MOVX @Ri,A 1 2
MOV @Ri,#data 2 1
MOVX @DPTR,A 1 2
MOV Rn,A 1 1
PUSH direct 2 2
MOV Rn,direct 2 2
POP direct 2 2
MOV Rn,#data 2 1
XCH A,@Ri 1 1
MOV direct,A 2 1
XCH A,Rn 1 1
MOV direct,@Ri 2 2
XCH A,direct 2 1
MOV direct,Rn 2 2
XCHD A,@Ri 1 1
MOV direct,direct 3 2
MOV direct,#data 3 2
8051的匯編控制指令,占用字節(jié),執(zhí)行周期列表2.
Logical opreations:
ANL A,@Ri 1 1
XRL A,@Ri 1 1
ANL A,Rn 1 1
XRL A,Rn 1 1
ANL A,direct 2 1
XRL A,direct 2 1
ANL A,#data 2 1
XRL A,#data 2 1
ANL direct,A 2 1
XRL direct,A 2 1
ANL direct,#data 3 2
XRL direct,#data 3 2
ORL A,@Ri 1 1
CLR A 1 1
ORL A,Rn 1 1
CPL A 1 1
ORL A,direct 2 1
RL A 1 1
ORL A,#data 2 1
RLC A 1 1
ORL direct,A 2 1
RR A 1 1
ORL direct,#data 3 2
RRC A 1 1
SWAP A 1 1
8051的匯編控制指令,占用字節(jié),執(zhí)行周期列表4.Boolean variable manipulation:
Mnemonic Byte Cyc
CLR C 1 1
ANL C,bit 2 2
SETB C 1 1
ANL C,/bit 2 2
CPL C 1 1
ORL C,bit 2 2
CLR bit 2 1
ORL C,/bit 2 2
SETB bit 2 1
MOV C,bit 2 1
CPL bit 2 1
MOV bit,C 2 2
8051的匯編控制指令,占用字節(jié),執(zhí)行周期列表
5.Program and machine control:
Mnemonic Byte Cyc
NOP 1 1
JZ rel 2 2
RET 1 2
JNZ rel 2 2
RETI 1 2
JC rel 2 2
ACALL addr11 2 2
JNC rel 2 2
AJMP addr11 2 2
JB bit,rel 3 2
LCALL addr16 3 2
JNB bit,rel 3 2
LJMP addr16 3 2
JBC bit,rel 3 2
SJMP rel 2 2
CJNE A,direct,rel 3 2
JMP @A+DPTR 1 2
CJNE A,#data,rel 3 2
DJNZ Rn,rel 2 2
CJNE @Ri,#data,rel 3 2
DJNZ direct,rel 3 2
CJNE Rn,#data,rel 3 2
匯編語(yǔ)言入門(mén)教程
一、所有電腦語(yǔ)言寫(xiě)出的程序運(yùn)行時(shí)在內(nèi)存中都以機(jī)器碼方式存儲(chǔ),機(jī)器碼可以被比較準(zhǔn)確的翻譯成匯編語(yǔ)言,這是因?yàn)閰R編語(yǔ)言兼容性最好,故幾乎所有跟蹤、調(diào)試工具(包括WIN95/98下)都是以匯編示人的,如果閣下對(duì)CRACK頗感興趣……;二、匯編直接與硬件打交道,如果你想搞通程序在執(zhí)行時(shí)在電腦中的來(lái)龍去脈,也就是搞清電腦每個(gè)組成部分究竟在干什么、究竟怎么干?一個(gè)真正的硬件發(fā)燒友,不懂這些可不行。三、如今玩DOS的多是“高手”,如能像吾一樣混入(我不是高手)“高手”內(nèi)部,不僅可以從“高手”朋友那兒套些黑客級(jí)“機(jī)密”,還可以自詡“高手”盡情享受強(qiáng)烈的虛榮感--#$%& “醒醒!”
對(duì)初學(xué)者而言,匯編的許多命令太復(fù)雜,往往學(xué)習(xí)很長(zhǎng)時(shí)間也寫(xiě)不出一個(gè)漂漂亮亮的程序,以致妨礙了我們學(xué)習(xí)匯編的興趣,不少人就此放棄。所以我個(gè)人看法學(xué)匯編,不一定要寫(xiě)程序,寫(xiě)程序確實(shí)不是匯編的強(qiáng)項(xiàng),大家不妨玩玩DEBUG,有時(shí)CRACK出一個(gè)小軟件比完成一個(gè)程序更有成就感(就像學(xué)電腦先玩游戲一樣)。某些高深的指令事實(shí)上只對(duì)有經(jīng)驗(yàn)的匯編程序員有用,對(duì)我們而言,太過(guò)高深了。為了使學(xué)習(xí)匯編語(yǔ)言有個(gè)好的開(kāi)始,你必須要先排除那些華麗復(fù)雜的命令,將注意力集中在最重要的幾個(gè)指令上(CMP LOOP MOV JNZ……)。但是想在啰里吧嗦的教科書(shū)中完成上述目標(biāo),談何容易,所以本人整理了這篇超濃縮(用WINZIP、WINRAR…依次壓迫,嘿嘿?。┙坛獭4笱圆粦M的說(shuō),看通本文,你完全可以“不經(jīng)意”間在前輩或是后生賣(mài)弄一下DEBUG,很有成就感的,試試看!那么――這個(gè)接下來(lái)呢?―― Here we go?。ㄩ喿x時(shí)看不懂不要緊,下文必有分解)
因?yàn)閰R編是通過(guò)CPU和內(nèi)存跟硬件對(duì)話(huà)的,所以我們不得不先了解一下CPU和內(nèi)存:(關(guān)于數(shù)的進(jìn)制問(wèn)題在此不提)
?。茫校帐强梢詧?zhí)行電腦所有算術(shù)╱邏輯運(yùn)算與基本 I/O 控制功能的一塊芯片。一種匯編語(yǔ)言只能用于特定的CPU。也就是說(shuō),不同的CPU其匯編語(yǔ)言的指令語(yǔ)法亦不相同。個(gè)人電腦由1981年推出至今,其CPU發(fā)展過(guò)程為:8086→80286→80386→80486→PENTIUM →……,還有AMD、CYRIX等旁支。后面兼容前面CPU的功能,只不過(guò)多了些指令(如多能奔騰的MMX指令集)、增大了寄存器(如386的32位EAX)、增多了寄存器(如486的FS)。為確保匯編程序可以適用于各種機(jī)型,所以推薦使用8086匯編語(yǔ)言,其兼容性最佳。本文所提均為8086匯編語(yǔ)言。
寄存器(Register)是CPU內(nèi)部的元件,所以在寄存器之間的數(shù)據(jù)傳送非??臁?div>
用途:
1.可將寄存器內(nèi)的數(shù)據(jù)執(zhí)行算術(shù)及邏輯運(yùn)算。
2.存于寄存器內(nèi)的地址可用來(lái)指向內(nèi)存的某個(gè)位置,即尋址。
3.可以用來(lái)讀寫(xiě)數(shù)據(jù)到電腦的周邊設(shè)備。
8086 有8個(gè)8位數(shù)據(jù)寄存器,這些8位寄存器可分別組成16位寄存器:
AH&AL=AX:累加寄存器,常用于運(yùn)算;
BH&BL=BX:基址寄存器,常用于地址索引;
CH&CL=CX:計(jì)數(shù)寄存器,常用于計(jì)數(shù);
DH&DL=DX:數(shù)據(jù)寄存器,常用于數(shù)據(jù)傳遞。
為了運(yùn)用所有的內(nèi)存空間,8086設(shè)定了四個(gè)段寄存器,專(zhuān)門(mén)用來(lái)保存段地址:CS(Code Segment):代碼段寄存器;
DS(Data Segment):數(shù)據(jù)段寄存器;
SS(Stack Segment):堆棧段寄存器;
ES(Extra Segment):附加段寄存器。
當(dāng)一個(gè)程序要執(zhí)行時(shí),就要決定程序代碼、數(shù)據(jù)和堆棧各要用到內(nèi)存的哪些位置,通過(guò)設(shè)定段寄存器 CS,DS,SS 來(lái)指向這些起始位置。通常是將DS固定,而根據(jù)需要修改CS。所以,程序可以在可尋址空間小于64K的情況下被寫(xiě)成任意大小。所以,程序和其數(shù)據(jù)組合起來(lái)的大小,限制在DS 所指的64K內(nèi),這就是COM文件不得大于64K的原因。8086以?xún)?nèi)存做為戰(zhàn)場(chǎng),用寄存器做為軍事基地,以加速工作。除了前面所提的寄存器外,還有一些特殊功能的寄存器:
IP(Intruction Pointer):指令指針寄存器,與CS配合使用,可跟蹤程序的執(zhí)行過(guò)程;
SP(Stack Pointer):堆棧指針,與SS配合使用,可指向目前的堆棧位置。
BP(Base Pointer):基址指針寄存器,可用作SS的一個(gè)相對(duì)基址位置;
SI(Source Index):源變址寄存器可用來(lái)存放相對(duì)于DS段之源變址指針;
DI(Destination Index):目的變址寄存器,可用來(lái)存放相對(duì)于 ES 段之目的變址指針。
還有一個(gè)標(biāo)志寄存器FR(Flag Register),有九個(gè)有意義的標(biāo)志,將在下文用到時(shí)詳細(xì)說(shuō)明。
內(nèi)存是電腦運(yùn)作中的關(guān)鍵部分,也是電腦在工作中儲(chǔ)存信息的地方。內(nèi)存組織有許多可存放數(shù)值的儲(chǔ)存位置,叫“地址”。8086地址總線(xiàn)有20位,所以CPU擁有達(dá)1M的尋址空間,這也是DOS的有效控制范圍,而8086能做的運(yùn)算僅限于處理16位數(shù)據(jù),即只有0到64K,所以,必須用分段尋址才能控制整個(gè)內(nèi)存地址。
完整的20位地址可分成兩部份:
1.段基址(Segment):16位二進(jìn)制數(shù)后面加上四個(gè)二進(jìn)制0,即一個(gè)16進(jìn)制0,變成20位二進(jìn)制數(shù),可設(shè)定1M中任何一個(gè)64K段,通常記做16位二進(jìn)制數(shù);2.偏移量(Offset):直接使用16位二進(jìn)制數(shù),指向段基址中的任何一個(gè)地址。如:2222(段基址):3333(偏移量),(22220+3333)其實(shí)際的20位地址值為:25553。除了上述營(yíng)養(yǎng)要充分吸收外,你還要知道什么是DOS、BIOS功能調(diào)用,簡(jiǎn)單的說(shuō),功能調(diào)用類(lèi)似于WIN95 API,相當(dāng)于子程序。匯編寫(xiě)程序已經(jīng)夠要命了,如果不用MS、IBM的子程序,這日子真是沒(méi)法過(guò)了(關(guān)于功能調(diào)用詳見(jiàn)《電腦愛(ài)好者》98年11期)。
編寫(xiě)匯編語(yǔ)言有兩種主要的方法:1.使用MASM或TASM等編譯器;2.使用除錯(cuò)程序DEBUG.COM。DEBUG其實(shí)并不能算是一個(gè)編譯器,它的主要用途在于除錯(cuò),即修正匯編程序中的錯(cuò)誤。不過(guò),也可以用來(lái)寫(xiě)短的匯編程序,尤其對(duì)初學(xué)者而言,DEBUG 更是最佳的入門(mén)工具。因?yàn)镈EBUG操作容易:只要鍵入DEBUG回車(chē),A回車(chē)即可進(jìn)行匯編,過(guò)程簡(jiǎn)單,而使用編譯器時(shí),必須用到文本編輯器、編譯器本身、LINK以及EXE2BIN等程序,其中每一個(gè)程序都必須用到一系列相當(dāng)復(fù)雜的命令才能工作,而且用編譯器處理源程序,必須加入許多與指令語(yǔ)句無(wú)關(guān)的指示性語(yǔ)句,以供編譯器識(shí)別,使用 DEBUG 可以避免一開(kāi)始就碰到許多難以理解的程序行。DEBUG 除了能夠匯編程序之外,還可用來(lái)檢查和修改內(nèi)存位置、載入儲(chǔ)存和執(zhí)行程序、以及檢查和修改寄存器,換句話(huà)說(shuō),DEBUG是為了讓我們接觸硬件而設(shè)計(jì)的。(8086常用指令用法將在每個(gè)匯編程序中講解,限于篇幅,不可能將所有指令列出)。
DEBUG的的A命令可以匯編出簡(jiǎn)單的COM文件,所以DEBUG編寫(xiě)的程序一定要由地址 100h(COM文件要求)開(kāi)始才合法。FOLLOW ME,SETP BY SETP(步步回車(chē)):
輸入 A100 ; 從DS:100開(kāi)始匯編
2.輸入 MOV DL,1 ; 將數(shù)值 01h 裝入 DL 寄存器
3.輸入 MOV AH,2 ; 將數(shù)值 02h 裝入 DL 寄存器
4.輸入 INT 21 ; 調(diào)用DOS 21號(hào)中斷2號(hào)功能,用來(lái)逐個(gè)顯示裝入DL的字符
5.輸入 INT 20 ; 調(diào)用DOS 20號(hào)中斷,終止程序,將控制權(quán)交回給 DEBUG
6.請(qǐng)按 Enter 鍵
7.現(xiàn)在已將匯編語(yǔ)言程序放入內(nèi)存中了,輸入 G(運(yùn)行)
8.出現(xiàn)結(jié)果:輸出一個(gè)符號(hào)。
ㄖ ←輸出結(jié)果其實(shí)不是它,因WORD97無(wú)法顯示原結(jié)果,故找一贗品將就著。
Program terminated normally
我們可以用U命令將十六進(jìn)制的機(jī)器碼反匯編(Unassemble)成匯編指令。你將發(fā)現(xiàn)每一行右邊的匯編指令就是被匯編成相應(yīng)的機(jī)器碼,而8086實(shí)際上就是以機(jī)器碼來(lái)執(zhí)行程序。
1.輸入 U100,106
1FED:0100 B201 MOV DL,01
1FED:0102 B402 MOV AH,02
1FED:0104 CD21 INT 21
1FED:0106 CD20 INT 20
DEBUG可以用R命令來(lái)查看、改變寄存器內(nèi)容。CS:IP寄存器,保存了將執(zhí)行指令地址。
1.輸入R
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFEE BP=0000 SI=0000 DI=0000
DS=1FED ES=1FED SS=1FED CS=1FED IP=0100 NV UP EI PL NZ NA PO NC
1FED:0100 B201 MOV DL,01
當(dāng)程序由DS:100開(kāi)始執(zhí)行,那么終止程序時(shí),DEBUG會(huì)自動(dòng)將IP內(nèi)容重新設(shè)定為100。當(dāng)你要將此程序做成一個(gè)獨(dú)立的可執(zhí)行文件,則可以用N命令對(duì)該程序命名。但一定要為COM文件,否則無(wú)法以DEBUG載入。
輸入N SMILE.COM ;我們得告訴DEBUG程序長(zhǎng)度:程序從100開(kāi)始到106,故占用7
;字節(jié)。我們利用BX存放長(zhǎng)度值高位部分,而以CX存放低位部分。
2.輸入RBX ;查看 BX 寄存器的內(nèi)容,本程序只有7個(gè)字節(jié),故本步可省略
3.輸入 RCX ;查看 CX 寄存器的內(nèi)容
4.輸入 7 ;程序的字節(jié)數(shù)
5.輸入 W ;用W命令將該程序?qū)懭耄╓rite)磁盤(pán)中
修行至此,我們便可以真正接觸8086匯編指令了。當(dāng)我們寫(xiě)匯編語(yǔ)言程序的時(shí)候,通常不會(huì)直接將機(jī)器碼放入內(nèi)存中,而是打入一串助記符號(hào)(Mnemonic Symbols),這些符號(hào)比十六進(jìn)制機(jī)器碼更容易記住,此之謂匯編指令。助記符號(hào),告訴CPU應(yīng)執(zhí)行何種運(yùn)算。也就是說(shuō),助憶符號(hào)所構(gòu)成的匯編語(yǔ)言是為人設(shè)計(jì)的,而機(jī)器語(yǔ)言是對(duì)PC設(shè)計(jì)的。
現(xiàn)在,我們?cè)賮?lái)剖析一個(gè)可以將所有ASCII碼顯示出來(lái)的程序。
1. 輸入 DEBUG
2. 輸入 A100
3.輸入 MOV CX,0100 ;裝入循環(huán)次數(shù)
MOV DL,00 ;裝入第一個(gè)ASCII碼,隨后每次循環(huán)裝入新碼
MOV AH,02
INT 21
INC DL ;INC:遞增指令,每次將數(shù)據(jù)寄存器 DL 內(nèi)的數(shù)值加 1
LOOP 0105 ;LOOP:循環(huán)指令,每執(zhí)行一次LOOP,CX值減1,并跳
;到循環(huán)的起始地址105,直到CX為0,循環(huán)停止
INT 20
4.輸入 G即可顯示所有ASCII碼
當(dāng)我們想任意顯示字符串,如:UNDERSTAND?,則可以使用DOS21H號(hào)中斷9H號(hào)功能。輸入下行程序,存盤(pán)并執(zhí)行看看: