




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第5章 控制轉(zhuǎn)移和程序結(jié)構(gòu),制作 錢曉捷,微型計(jì)算機(jī)原理及應(yīng)用,2006年,第5章 控制轉(zhuǎn)移和程序結(jié)構(gòu),5.1 目標(biāo)地址尋址方式 5.1.1轉(zhuǎn)移范圍 5.1.2尋址方式 5.1.3 無條件轉(zhuǎn)移指令 5.2 分支程序結(jié)構(gòu) 5.2.1 條件轉(zhuǎn)移指令 5.2.2 單分支結(jié)構(gòu) 5.2.3 雙分支結(jié)構(gòu) 5.2.4 多分支結(jié)構(gòu),5.3 循環(huán)程序結(jié)構(gòu) 5.3.1 循環(huán)指令 5.3.2 計(jì)數(shù)控制循環(huán) 5.3.3 條件控制循環(huán) 5.4 子程序結(jié)構(gòu) 5.4.1 子程序指令 5.4.2 子程序設(shè)計(jì) 5.4.3 參數(shù)傳遞 5.4.4 程序模塊,目標(biāo)地址,程序代碼在代碼段 CS:指明代碼段在主存中的開始位置、即段基地址
2、 EIP:給出將要執(zhí)行指令的偏移地址 程序順序執(zhí)行,微處理器自動(dòng)增量EIP 程序控制轉(zhuǎn)移,EIP隨之改變 程序轉(zhuǎn)移到另外的代碼段, EIP和CS都將改變 控制轉(zhuǎn)移類指令:改變EIP(有些也改變CS),即改變程序執(zhí)行順序(實(shí)現(xiàn)程序控制轉(zhuǎn)移)的指令 目標(biāo)地址尋址方式:改變CS和EIP寄存器,或者說如何指明目的地、即目標(biāo)地址的方法,目標(biāo)地址目的地址轉(zhuǎn)移地址,轉(zhuǎn)移范圍,段內(nèi)轉(zhuǎn)移 在當(dāng)前代碼段范圍內(nèi)的程序轉(zhuǎn)移 不需更改CS,只要改變EIP(偏移地址) 也稱近轉(zhuǎn)移(Near):16位段是16位近轉(zhuǎn)移NEAR16, 32位段是32位近轉(zhuǎn)移NEAR32 短轉(zhuǎn)移(Short):轉(zhuǎn)移范圍在127-128字節(jié) 段間
3、轉(zhuǎn)移 從當(dāng)前代碼段跳轉(zhuǎn)到另一個(gè)代碼段 需要更改CS(段地址)和EIP(偏移地址) 可在整個(gè)程序控件內(nèi)跳轉(zhuǎn),也稱遠(yuǎn)轉(zhuǎn)移(Far):16位段是32位遠(yuǎn)轉(zhuǎn)移FAR16指針, 32位段是48位遠(yuǎn)轉(zhuǎn)移FAR32指針,標(biāo)號(hào)、邏輯段名、子程序名等標(biāo)識(shí)符具有地址和類型屬性。 獲得地址屬性:OFFSET/SEG; 獲得類型值:TYPE; 強(qiáng)制轉(zhuǎn)換類型:PTR。 段轉(zhuǎn)移、近轉(zhuǎn)移、遠(yuǎn)轉(zhuǎn)移的類姓名:SHORT/NEAR/FAR,目標(biāo)地址尋址方式,相對(duì)尋址方式 提供目標(biāo)地址相對(duì)于當(dāng)前指令指針EIP的位移量 目標(biāo)地址(轉(zhuǎn)移后的EIP)當(dāng)前EIP位移量 相對(duì)尋址都是段內(nèi)轉(zhuǎn)移,最常用、最靈活 直接尋址方式 直接提供目標(biāo)地址
4、目標(biāo)地址(轉(zhuǎn)移后的CS和EIP)指令操作數(shù) 間接尋址方式 指示寄存器或存儲(chǔ)單元 目標(biāo)地址來自寄存器或存儲(chǔ)單元、間接獲得 寄存器間接尋址:用寄存器保存目標(biāo)地址 存儲(chǔ)器間接尋址:用存儲(chǔ)單元保存目標(biāo)地址,無條件轉(zhuǎn)移指令JMP,無條件轉(zhuǎn)移:程序無條件改變執(zhí)行順序 JMP指令相當(dāng)于高級(jí)語(yǔ)言的goto語(yǔ)句 JMP label ;程序轉(zhuǎn)向label標(biāo)號(hào)指定的地址 ;段內(nèi)相對(duì)尋址,段間直接尋址 JMP reg16/reg32 ;程序轉(zhuǎn)向寄存器指定的地址 ;寄存器間接尋址 JMP mem16/mem32 ;程序轉(zhuǎn)向存儲(chǔ)單元指定的地址 ;存儲(chǔ)器間接尋址,JMP指令的4種類型,1. 段內(nèi)轉(zhuǎn)移、相對(duì)尋址 標(biāo)號(hào)指明目標(biāo)
5、地址,指令代碼包含位移量 2. 段內(nèi)轉(zhuǎn)移、間接尋址 通用寄存器或主存單元包含目標(biāo)指令的偏移地址 3. 段間轉(zhuǎn)移、直接尋址 標(biāo)號(hào)包含目標(biāo)指令的段地址和偏移地址 4. 段間轉(zhuǎn)移、間接尋址 16位段用雙字存儲(chǔ)單元包含目標(biāo)地址 32位段用3字存儲(chǔ)單元包含目標(biāo)地址,MASM會(huì)根據(jù)存儲(chǔ)模式等信息自動(dòng)識(shí)別,演示,例題5-1無條件轉(zhuǎn)移程序-1,;數(shù)據(jù)段 0000 0000nvardw ? ;代碼段 0010 EB 01jmp labl1 0012 90nop 0013 B8 FF02labl1:mov ax,type labl1 0016 E9 0001jmp near ptr labl2 0019 90no
6、p 001A B8 0020 Rlabl2:mov ax,offset labl3 001D FF E0jmp ax 001F 90nop 0020 B8 002B Rlabl3:mov ax,offset labl4 0023 A3 0000 Rmov nvar,ax 0026 FF 26 0000 Rjmp nvar 002A 90nop,例題5-1無條件轉(zhuǎn)移程序-2,;數(shù)據(jù)段 0002 00000000fvardd ? ;代碼段 002B B8 FF05labl4:mov ax,type far ptr labl5 002E EA - 0034 Rjmp far ptr labl5 00
7、33 90nop 0034 B8 0047 Rlabl5:mov ax,offset labl6 0037 A3 0002 Rmov word ptr fvar,ax 003A BA - Rmov dx,seg labl6 003D 89 16 0004 Rmov word ptr fvar+2,dx 0041 FF 2E 0002 Rjmp fvar 0045 90nop 0046labl6:,調(diào)試,條件轉(zhuǎn)移指令Jcc,根據(jù)指定的條件確定程序是否發(fā)生轉(zhuǎn)移 Jcc label ;條件滿足,發(fā)生轉(zhuǎn)移;否則,順序執(zhí)行下一條指令 LABEL表示目標(biāo)地址,采用段內(nèi)相對(duì)尋址方式 16位80 x86微處理
8、器:只是-128+127間的短轉(zhuǎn)移 32位IA-32微處理器:達(dá)到32位的全偏移量 條件轉(zhuǎn)移指令不影響標(biāo)志,但要利用標(biāo)志 cc表示利用標(biāo)志判斷的條件,16種、兩類 單個(gè)標(biāo)志狀態(tài)作為條件 兩數(shù)大小關(guān)系作為條件,轉(zhuǎn)移條件cc:?jiǎn)蝹€(gè)標(biāo)志狀態(tài),/分隔同一命令多個(gè)助記符,JZ/JEZF=1Jump if Zero/Equal JNZ/JNEZF=0Jump if Not Zero/Not Equal JSSF=1Jump if Sign JNSSF=0Jump if Not Sign JP/JPEPF=1Jump if Parity/Parity Even JNP/JPOPF=0Jump if Not
9、Parity/Parity Odd JOOF=1Jump if Overflow JNOOF=0Jump if Not Overflow JCCF=1Jump if Carry JNCCF=0Jump if Not Carry,兩數(shù)大小關(guān)系作為條件,無符號(hào)數(shù)用高(Above)、低(Below) 低于(不高于等于):JB(JNAE) 不低于(高于等于):JNB(JAE) 低于等于(不高于):JBE(JNA) 不低于等于(高于):JNBE(JA) 有符號(hào)數(shù)用大(Greater)、?。↙ess) 小于(不大于等于):JL(JNGE) 不小于(大于等于):JNL(JGE) 小于等于(不大于):JLE(
10、JNG) 不小于等于(大于):JNLE(JG),轉(zhuǎn)移條件cc:兩數(shù)大小關(guān)系,JB/JNAECF=1Jump if Below/Not Above or Equal JNB/JAECF=0Jump if Not Below/Above or Equal JBE/JNACF=1或ZF=1Jump if Below/Not Above JNBE/JACF=0且ZF=0Jump if Not Below or Equal/Above JL/JNGESFOFJump if Less/Not Greater or Equal JNL/JGESF=OFJump if Not Less/Greater or
11、Equal JLE/JNGZFOF或ZF=1Jump if Less or Equal/Not Greater JNLE/JGSF=OF且ZF=0Jump if Not Less or Equal/Greater,多個(gè)助記符方便記憶,單個(gè)標(biāo)志狀態(tài)作為條件,JZ(JE)和JNZ(JNE):利用零位標(biāo)志ZF 判斷結(jié)果是零(相等)還是非零(不等) JS和JNS:利用符號(hào)標(biāo)志SF 判斷結(jié)果是負(fù)還是正 JO和JNO:利用溢出標(biāo)志OF 判斷結(jié)果是溢出還是沒有溢出 JP(JPE)和JNP(JPO):利用奇偶標(biāo)志PF 判斷結(jié)果低字節(jié)“1”的個(gè)數(shù)是偶數(shù)還是奇數(shù) JC和JNC:利用進(jìn)位標(biāo)志CF 判斷結(jié)果是有進(jìn)位(
12、為1)還是無進(jìn)位(為0),例題5-2實(shí)現(xiàn)指令CBW功能的程序-1,8086指令CBW(等于IA-32指令MOVSX AX,AL) 如果AL最高位為0,則設(shè)置AH0 如果AL最高位為1,則設(shè)置AHFFH 如何判斷AL最高位是“0”,還是“1” 涉及一個(gè)位,可采用位操作類指令 保留最高位不變,其他位變成0 邏輯與“80H”結(jié)果為0,AL最高位0;否則是1 運(yùn)算結(jié)果是否為0,零位標(biāo)志ZF反映 JZ或JNZ指令判斷并轉(zhuǎn)移,演示,TEST指令生成條件,例題5-2實(shí)現(xiàn)指令CBW功能的程序-2,mov al,bvar;取出要判斷的數(shù)據(jù) test al,80h;測(cè)試最高位 jz next1 ;最高位為0(ZF
13、1),轉(zhuǎn)移到標(biāo)號(hào)NEXT1 mov ah,0ffh ;最高位為1,順序執(zhí)行:設(shè)置AHFFH jmp done;無條件跳過另一個(gè)分支 next1:mov ah,0 ;最高位為0轉(zhuǎn)移到此執(zhí)行:設(shè)置AH0 done:,等于零轉(zhuǎn)移,例題5-2實(shí)現(xiàn)指令CBW功能的程序-3,mov al,bvar;取出要判斷的數(shù)據(jù) test al,80h;測(cè)試最高位 jnz next2 ;最高位為1(ZF0),轉(zhuǎn)移到標(biāo)號(hào)NEXT2 mov ah,0 ;最高位為0,順序執(zhí)行:設(shè)置AH00H jmp done;無條件跳過另一個(gè)分支 next2:mov ah,0ffh ;最高位為1轉(zhuǎn)移到此執(zhí)行:設(shè)置AHFFH done:,不等
14、于零轉(zhuǎn)移,例題5-2實(shí)現(xiàn)指令CBW功能的程序-4,mov al,bvar;取出要判斷的數(shù)據(jù) cmp al,0;與0比較 jns next3 ;最高位為0(SF0),轉(zhuǎn)移到標(biāo)號(hào)NEXT3 mov ah,0ffh ;最高位為1,順序執(zhí)行:設(shè)置AHFFH jmp done;無條件跳過另一個(gè)分支 next3:mov ah,0 ;最高位為0轉(zhuǎn)移到此執(zhí)行:設(shè)置AH00H done:,符號(hào)為正轉(zhuǎn)移,例題5-3實(shí)現(xiàn)奇偶校驗(yàn)程序-1,奇偶校驗(yàn)是數(shù)據(jù)通信、存儲(chǔ)等過程中最常用的校驗(yàn)方法 奇校驗(yàn):使包括校驗(yàn)位在內(nèi)的數(shù)據(jù)中為“1”的個(gè)數(shù)恒為奇數(shù) 偶校驗(yàn):使包括校驗(yàn)位在內(nèi)的數(shù)據(jù)中為“1”的個(gè)數(shù)恒為偶數(shù)(包括0) 奇偶校驗(yàn)
15、只能檢測(cè)出奇數(shù)個(gè)位出錯(cuò)的情況,不能糾錯(cuò) 實(shí)現(xiàn)奇偶校驗(yàn)非常簡(jiǎn)單 硬件上使用異或等電路 軟件上使用異或等指令,奇偶校驗(yàn)標(biāo)志PF,例題5-3實(shí)現(xiàn)奇偶校驗(yàn)程序-2,mov ah,1;1號(hào)功能 int 21h;鍵盤輸入,返回值在AL and al,7fh ;最高位置“0”,標(biāo)志PF反映“1”的個(gè)數(shù) jnp next1;個(gè)數(shù)為奇數(shù),則轉(zhuǎn)向NEXT1 or al,80h;最高位置“1”、其他位不變 next1:mov Tdata,al;保存待發(fā)送的數(shù)據(jù),個(gè)數(shù)為奇數(shù)轉(zhuǎn)移,例題5-3實(shí)現(xiàn)奇偶校驗(yàn)程序-3,mov ah,1;1號(hào)功能 int 21h;鍵盤輸入,返回值在AL and al,7fh ;最高位置“0”,
16、標(biāo)志PF反映“1”的個(gè)數(shù) jp next2;個(gè)數(shù)為偶數(shù),轉(zhuǎn)向NEXT2 jmp done;個(gè)數(shù)為奇數(shù),轉(zhuǎn)向保存 next2: or al,80h;最高位置“1”、其他位不變 done:mov Tdata,al;保存待發(fā)送的數(shù)據(jù),個(gè)數(shù)為偶數(shù)轉(zhuǎn)移,何不合二為一,例題5-4統(tǒng)計(jì)“1”位個(gè)數(shù)程序-1,mov ah,1 int 21h;輸入一個(gè)字符 xor ah,ah ;用AH寄存器記錄1的個(gè)數(shù),故先清0 mov ecx,8 ;ASCII碼有8位,進(jìn)行8次循環(huán)判斷 again:shl al,1;從高位開始 jnc next;不為1,無需處理 inc ah;為1,個(gè)數(shù)加1 next:loop again,
17、例題5-4統(tǒng)計(jì)“1”位個(gè)數(shù)程序-2,mov ah,1 int 21h;輸入一個(gè)字符 xor ah,ah ;用AH寄存器記錄1的個(gè)數(shù),故先清0 again:cmp al,0;也可用“TEST AL,0FFH” je done shr al,1;從低位開始 jnc next;不為1,無需處理 inc ah;為1,個(gè)數(shù)加1 next:jmp again done:,好在哪里?,例題5-5比較兩數(shù)大小程序,mov ax,wvar1;取第一個(gè)數(shù)據(jù) cmp ax,wvar2;與第二個(gè)數(shù)據(jù)比較 je equal;兩數(shù)相等,轉(zhuǎn)移 jnb first;第一個(gè)數(shù)據(jù)大,轉(zhuǎn)移 mov dx,offset msg2;第
18、二個(gè)數(shù)據(jù)大 jmp done first:mov dx,offset msg1 jmp done equal:mov dx,offset msg0 done:mov ah,9;顯示結(jié)果 int 21h,無符號(hào)數(shù) 有符號(hào)數(shù),單分支程序例題5-6求絕對(duì)值程序,;數(shù)據(jù)段 dvardd 0bd630422h;有符號(hào)數(shù)據(jù) resultdd ?;保存絕對(duì)值 ;代碼段 mov eax,dvar cmp eax,0;比較EAX與0 jge nonneg;條件滿足:AX0,轉(zhuǎn)移 neg eax ;條件不滿足:AX0,為負(fù)數(shù),需求補(bǔ)得正值 nonneg:mov result,eax;分支結(jié)束,保存結(jié)果,單分支,I
19、F-THEN結(jié)構(gòu),演示,單分支程序例題5-7BCD碼顯示程序,mov dl,BCD;取BCD碼 test dl,0f0h;如果高位是0,不顯示 jz one shr dl,4;BCD碼高位右移為低位 or dl,30h;轉(zhuǎn)換為ASCII碼 mov ah,2;顯示 int 21h mov dl,BCD;取BCD碼 and dl,0fh;只取二進(jìn)制低4位 one:or dl,30h;轉(zhuǎn)換低位為ASCII碼 mov ah,2;顯示 int 21h,add dl,30h,雙分支例題5-8顯示數(shù)據(jù)最高位程序-1,;數(shù)據(jù)段 dvardd 0bd630422h;有符號(hào)數(shù)據(jù) ;代碼段 mov ebx,dvar
20、 shl ebx,1;EBX最高位移入CF標(biāo)志 jc one;CF1,最高位為1,轉(zhuǎn)移 mov dl,0;CF0,最高位為0:DL0 jmp two;一定要跳過另一個(gè)分支體 one:mov dl,1;DL1 two:mov ah,2 int 21h;顯示,雙分支,IF-THEN-ELSE結(jié)構(gòu),演示,例題5-8顯示數(shù)據(jù)最高位程序-2,;數(shù)據(jù)段 dvardd 0bd630422h;有符號(hào)數(shù)據(jù) ;代碼段 mov ebx,dvar mov dl,0;假設(shè)最高位為0:DL0 shl ebx,1;EBX最高位移入CF標(biāo)志jnc two ;CF0,即最高位為0、與假設(shè)相同,轉(zhuǎn)移 mov dl,1;CF1,最
21、高位為1,DL1 two:mov ah,2 int 21h;顯示,IF-THEN結(jié)構(gòu),例題5-8顯示數(shù)據(jù)最高位程序-3,;數(shù)據(jù)段 dvardd 0bd630422h;有符號(hào)數(shù)據(jù) ;代碼段 mov ebx,dvar mov dl,0 shl ebx,1;EBX最高位移入CF標(biāo)志 adc dl,0 ;最高位為0,CF0,DL000 ;最高位為1,CF1,DL101 mov ah,2;顯示 int 21h,順序結(jié)構(gòu),例題5-9有符號(hào)數(shù)運(yùn)算溢出程序,;代碼段 mov eax,dvar1 sub eax,dvar2;求差 jo error;有溢出,轉(zhuǎn)移 mov dvar3,eax;無溢出,保存差值 le
22、a dx,okmsg;顯示正確 jmp disp error:lea dx,errmsg;顯示錯(cuò)誤 disp:mov ah,9 int 21h,分支程序結(jié)構(gòu),單分支程序結(jié)構(gòu) 選好條件轉(zhuǎn)移指令:當(dāng)條件滿足,發(fā)生轉(zhuǎn)移,跳過分支體;條件不滿足,順序執(zhí)行分支體 雙分支程序結(jié)構(gòu) 順序執(zhí)行的分支體要有JMP指令跳過另一個(gè)分支體 多分支結(jié)構(gòu) 分支處理中又有分支,具有多個(gè)分支走向 可用單分支和雙分支實(shí)現(xiàn)多個(gè)分支結(jié)構(gòu) or ah,ah jz function0 dec ah jz function1 ,例題5-10利用地址表實(shí)現(xiàn)多分支程序-1,;數(shù)據(jù)段 msgdb Input number(19): ,$ cr
23、lfdb 0dh,0ah,$ msg1db Chapter 1 ,0dh,0ah,$ msg9db Chapter 9,0dh,0ah,$ tabledw disp1,disp2,disp3,disp4,disp5 dw disp6,disp7,disp8,disp9;入口地址表,例題5-10利用地址表實(shí)現(xiàn)多分支程序-2,;代碼段 start1:mov dx,offset msg;提示輸入數(shù)字 mov ah,9 int 21h mov ah,1;等待按鍵 int 21h push ax mov dx,offset crlf;回車換行 mov ah,9 int 21h pop ax;AL數(shù)字的A
24、SCII碼,例題5-10利用地址表實(shí)現(xiàn)多分支程序-3,cmp al,1;數(shù)字 9? ja start1 and ax,000fh;ASCII碼轉(zhuǎn)換成數(shù)字 dec ax shl ax,1;乘以2 mov bx,ax jmp tablebx ;段內(nèi)存儲(chǔ)器間接轉(zhuǎn)移:IPTABLEBX disp1:mov dx,offset msg1;分支程序1 jmp start2,例題5-10利用地址表實(shí)現(xiàn)多分支程序-4,jmp tablebx;IPTABLEBX ;地址尋址方式:存儲(chǔ)器間接轉(zhuǎn)移 ;數(shù)據(jù)尋址方式:寄存器相對(duì)尋址,循環(huán)程序結(jié)構(gòu)while或do-while,循環(huán)指令,LOOP label ;ECXEC
25、X1;若ECX0,循環(huán)到LABEL; ;否則,順序執(zhí)行 JECXZ label ;ECX0,轉(zhuǎn)移;否則順序執(zhí)行 JCXZ label ;CX0,轉(zhuǎn)移;否則順序執(zhí)行 32位段使用ECX(16位段使用CX)作為計(jì)數(shù)器 目標(biāo)地址采用相對(duì)短轉(zhuǎn)移,例題5-11數(shù)組求和程序-1,arraydw 136,138,133,130,6776,6778,6713 sumdd ? ;代碼段 mov ecx,lengthof array xor eax,eax;求和初值為0 mov ebx,eax;數(shù)組指針為0 again:movzx edx,arrayebx*(type array) add eax,edx;求和
26、inc ebx loop again mov sum,eax;保存結(jié)果,例題5-11數(shù)組求和程序-2(改進(jìn)),mov ecx,lengthof array xor eax,eax;求和初值為0 jecxz done ;數(shù)組元素為0,不再進(jìn)行求和 mov ebx,eax;數(shù)組指針為0 again:movzx edx,arrayebx*(type array) add eax,edx;求和 inc ebx loop again done:mov sum,eax;保存結(jié)果,字符串輸入功能,例題5-12輸入字符串大小寫轉(zhuǎn)換程序-1,;數(shù)據(jù)段 keynum= 255 keybufdb keynum;鍵盤
27、輸入緩沖區(qū) db 0 db keynum dup(0) ;代碼段 mov dx,offset keybuf;設(shè)置入口參數(shù)DX mov ah,0ah int 21h;用戶用回車鍵結(jié)束 mov dl,0ah;回車后再進(jìn)行換行 mov ah,2 int 21h,輸入“Hi”,回車,緩沖區(qū): FF 02 48 69 0D 00 ,例題5-12輸入字符串大小寫轉(zhuǎn)換程序-2,mov bx,offset keybuf+1;輸入字符個(gè)數(shù) mov cl,bx mov ch,0;作為循環(huán)的次數(shù) again:inc bx;BX指向輸入字符 mov dl,bx;取出一個(gè)字符 cmp dl,a;小于小寫字母“a” jb
28、 disp cmp dl,z;大于小寫字母“z” ja disp;直接去顯示 sub dl,20h;小寫字母轉(zhuǎn)換為大寫字母 disp:mov ah,2;顯示一個(gè)字符 int 21h loop again;循環(huán),計(jì)數(shù)控制循環(huán),循環(huán)控制,計(jì)數(shù)控制循環(huán) 通過次數(shù)控制循環(huán),常用LOOP指令實(shí)現(xiàn) 條件控制循環(huán) 根據(jù)條件決定是否進(jìn)行循環(huán),需用條件轉(zhuǎn)移指令 “先判斷、后循環(huán)”的循環(huán)程序結(jié)構(gòu) 循環(huán)控制在進(jìn)入循環(huán)之前進(jìn)行 “先循環(huán)、后判斷”的循環(huán)程序結(jié)構(gòu) 循環(huán)之后進(jìn)行循環(huán)條件判斷,示意圖,例題5-13記錄字符串特定字符個(gè)數(shù)程序,mov esi,offset string xor ebx,ebx;EBX用于記錄空
29、格數(shù) again:mov al,esi cmp al,0 jz done cmp al,20h;空格的ASCII碼是20H jne next;不相等、不是空格,轉(zhuǎn)移 inc bx;相等、是空格,個(gè)數(shù)加1 next:inc esi jmp again;繼續(xù)循環(huán) done:mov space,ebx;保存結(jié)果,條件控制循環(huán),例題5-14剔除字符串中特定字符程序,mov esi,offset string outlp:cmp byte ptr esi,$;外循環(huán) jz done;為“$”字符,結(jié)束 again:cmp byte ptr esi, ;檢測(cè)是否是空格 jnz next;不是空格繼續(xù)循環(huán)
30、mov edi,esi;是空格,剔除空格分支 inlp:inc edi;該分支是循環(huán)程序 mov al,edi;前移一個(gè)位置 mov edi-1,al cmp byte ptr edi,$;內(nèi)循環(huán) jnz inlp jmp again;內(nèi)循環(huán)結(jié)束處 next:inc esi;繼續(xù)對(duì)后續(xù)字符處理 jmp outlp;外循環(huán)結(jié)束處 done:.,先循環(huán)后判斷,先判斷后循環(huán),多重循環(huán),子程序結(jié)構(gòu),子程序:與主程序分開的、完成特定功能的一段程序 當(dāng)主程序(調(diào)用程序)執(zhí)行調(diào)用指令CALL調(diào)用子程序 子程序(被調(diào)用程序)執(zhí)行返回指令RET返回主程序,回到CALL指令后的指令處返回地址,子程序調(diào)用指令CAL
31、L,CALL指令用在主程序中,實(shí)現(xiàn)子程序的調(diào)用 分成段內(nèi)調(diào)用(近調(diào)用)和段間調(diào)用(遠(yuǎn)調(diào)用) 目標(biāo)地址采用相對(duì)尋址、直接尋址或間接尋址 入棧返回地址:將CALL下一條指令的地址壓入堆棧 16位段段內(nèi):16位偏移地址,段間:再加16位段地址 32位段段內(nèi):32位偏移地址,段間:再將16位段選擇器零位擴(kuò)展為32位保存到堆棧 CALL label ;調(diào)用標(biāo)號(hào)指定的子程序 CALL reg16/reg32 ;調(diào)用寄存器指定地址的子程序 CALL mem16/mem32 ;調(diào)用存儲(chǔ)單元指定地址的子程序,子程序返回指令RET,RET指令用在子程序結(jié)束,實(shí)現(xiàn)返回主程序 RET ;無參數(shù)返回:出棧返回地址 RE
32、T i16 ;有參數(shù)返回:出棧返回地址,ESPESPi16,MASM會(huì)根據(jù)存儲(chǔ)模式等信息確定子程序的遠(yuǎn)近調(diào)用,并相應(yīng)產(chǎn)生返回指令,過程定義,MASM利用過程定義偽指令獲得子程序信息 過程名PROC ;過程體 過程名ENDP ;過程名為符合語(yǔ)法的標(biāo)識(shí)符 PROC后面可加參數(shù):NEAR或FAR 簡(jiǎn)化段定義源程序格式中,通常不需指定 微型、小型和緊湊存儲(chǔ)模式:默認(rèn)屬性NEAR 中型、大型和巨型存儲(chǔ)模式:默認(rèn)屬性FAR,例題5-15十六進(jìn)制轉(zhuǎn)換為ASCII碼程序-1,;代碼段(主程序) mov ax,wvar mov cx,4;共4位十六進(jìn)制數(shù) again:rol ax,4 push ax call
33、htoasc;調(diào)用子程序 mov ah,2 mov dl,al int 21h;顯示一個(gè)字符 pop ax loop again,子程序功能,不關(guān)心實(shí)現(xiàn),例題5-15十六進(jìn)制轉(zhuǎn)換為ASCII碼程序-2,;代碼段(子程序) htoascproc;過程定義 and al,0fh;只取AL的低4位 or al,30h;AL高4位變成3 cmp al,39h;是09,還是AF jbe htoend add al,7;是AF,再加上7 htoend:ret;子程序返回 htoascendp;過程結(jié)束,子程序功能,子程序設(shè)計(jì),利用過程定義,獲得子程序名和調(diào)用屬性 RET指令返回主程序,CALL指令調(diào)用子程
34、序 壓入和彈出操作要成對(duì)使用,保持堆棧平衡 開始保護(hù)寄存器,返回前相應(yīng)恢復(fù) 安排在代碼段的主程序之外 子程序允許嵌套和遞歸 即可共用一個(gè)數(shù)據(jù)段,也可具有獨(dú)立數(shù)據(jù)段,最好有完整的注釋,難點(diǎn)是參數(shù)傳遞,例題5-16字符串顯示程序-1,;數(shù)據(jù)段 msgdb Well, I made it !,0 ;代碼段(主程序) mov si,offset msg;主程序提供顯示字符串 call dpstri;調(diào)用子程序,例題5-16字符串顯示程序-2,;代碼段(子程序) dpstriproc;子程序:顯示字符串 push ax ;寄存器保護(hù) dps1:mov al,si;取顯示字符 cmp al,0;是結(jié)尾,則
35、顯示結(jié)束 jz dps2 call dpchar;調(diào)用字符顯示子程序 inc si jmp dps1 dps2:pop ax ;寄存器恢復(fù) ret dpstriendp,子程序嵌套,例題5-16字符串顯示程序-3,dpcharproc;子程序顯示字符 push ax;順序入棧,保護(hù)寄存器 push dx mov ah,2 mov dl,al;顯示一個(gè)字符 int 21h pop dx;逆序出棧,恢復(fù)寄存器 pop ax ret dpcharendp,例題5-17寄存器內(nèi)容顯示程序-1,;數(shù)據(jù)段 dvardd 1234abcdh regddb EAX= ;代碼段 mov ebx,offset r
36、egd mov ecx,4;顯示4個(gè)字符 dregd1:mov ah,2 mov dl,ebx int 21h inc ebx loop dregd1,例題5-17寄存器內(nèi)容顯示程序-2,mov ecx,8;共8位十六進(jìn)制數(shù) mov eax,dvar dregd2:rol eax,4 push eax call htoasc;調(diào)用子程序 mov ah,2 mov dl,al int 21h;顯示一個(gè)字符 pop eax loop dregd2,子程序功能,不關(guān)心實(shí)現(xiàn),例題5-17寄存器內(nèi)容顯示程序-3,htoascproc push ebx mov ebx,offset ASCII and a
37、l,0fh;取得一位十六進(jìn)制數(shù) xlat ASCII;換碼:ALCS:EBXAL pop ebx ret ;子程序的局部數(shù)據(jù)(在代碼段CS) ASCIIdb 30h,31h,32h,33h,34h db 35h,36h,37h,38h,39h db 41h,42h,43h,44h,45h,46h htoascendp,子程序的參數(shù)傳遞,主程序與子程序間通過參數(shù)傳遞建立聯(lián)系 入口參數(shù)(輸入?yún)?shù)):主程序子程序 出口參數(shù)(輸出參數(shù)):子程序主程序 傳遞參數(shù)的多少反映程序模塊間的耦合程度 參數(shù)的具體內(nèi)容 數(shù)據(jù)本身(傳遞數(shù)值) 數(shù)據(jù)的存儲(chǔ)地址(傳遞地址,傳遞引用) 參數(shù)傳遞方法:寄存器、變量或堆棧,寄
38、存器傳遞參數(shù),最簡(jiǎn)單和常用的參數(shù)傳遞方法 把參數(shù)存于約定的寄存器 少量數(shù)據(jù)直接傳遞數(shù)值 大量數(shù)據(jù)只能傳遞地址 帶有出口參數(shù)的寄存器不能保護(hù)和恢復(fù) 帶有入口參數(shù)的寄存器可以保護(hù)、也可以不保護(hù),但最好能夠保持一致 本書程序和DOS功能調(diào)用沒有保護(hù) 例如:反映功能號(hào)的AX 再如:09號(hào)調(diào)用的偏移地址DX,例題5-18有符號(hào)十進(jìn)制數(shù)輸入程序-1,算法如下: 首先判斷輸入正數(shù)還是負(fù)數(shù),并用一個(gè)寄存器記錄下來; 接著輸入09數(shù)字(ASCII碼),并減30H轉(zhuǎn)換為二進(jìn)制數(shù); 然后將前面輸入的數(shù)值乘10,并與剛輸入的數(shù)字相加得到新的數(shù)值; 重復(fù)2、3步,直到輸入一個(gè)非數(shù)字字符結(jié)束; 如果是負(fù)數(shù)進(jìn)行求補(bǔ),轉(zhuǎn)換成
39、補(bǔ)碼;否則直接將數(shù)值保存,例題5-18有符號(hào)十進(jìn)制數(shù)輸入程序-2,mov ecx,count mov ebx,offset array again:call readsid;輸入一個(gè)數(shù)據(jù) mov ebx,eax;存放出口參數(shù) add ebx,4 call dpcrlf;光標(biāo)回車換行 loop again,例題5-18有符號(hào)十進(jìn)制數(shù)輸入程序-3,readsidproc;輸入有符號(hào)十進(jìn)制數(shù)子程序 push ebx;說明:負(fù)數(shù)用“-”引導(dǎo) push ecx push edx xor ebx,ebx;EBX保存結(jié)果 xor ecx,ecx ;ECX為正負(fù)標(biāo)志:0為正,-1為負(fù),例題5-18有符號(hào)十進(jìn)制
40、數(shù)輸入程序-4,mov ah,1;輸入一個(gè)字符 int 21h cmp al,+;是“”,繼續(xù)輸入字符 jz rsid1 cmp al,-;是“”,設(shè)置1標(biāo)志 jnz rsid2 mov ecx,-1,例題5-18有符號(hào)十進(jìn)制數(shù)輸入程序-5,rsid1:mov ah,1;繼續(xù)輸入字符 int 21h rsid2:cmp al,0 ;不是09之間的字符,則輸入數(shù)據(jù)結(jié)束 jb rsid3 cmp al,9 ja rsid3 sub al,30h ;是09之間的字符,則轉(zhuǎn)換為二進(jìn)制數(shù),例題5-18有符號(hào)十進(jìn)制數(shù)輸入程序-6,imul ebx,10;數(shù)值乘10:EBXEBX10 movzx eax,a
41、l add ebx,eax;與新輸入數(shù)值相加 jmp rsid1;繼續(xù)輸入字符 rsid3:cmp ecx,0;是負(fù)數(shù),進(jìn)行求補(bǔ) jz rsid4 neg ebx rsid4:mov eax,ebx;設(shè)置出口參數(shù) pop edx pop ecx pop ebx ret;子程序返回 readsidendp,例題5-18有符號(hào)十進(jìn)制數(shù)輸入程序-7,dpcrlfproc;光標(biāo)回車換行子程序 push ax push dx mov ah,2 mov dl,0dh int 21h mov ah,2 mov dl,0ah int 21h pop dx pop ax ret dpcrlfendp,共享變量傳
42、遞參數(shù),子程序和主程序使用同一個(gè)變量名存取數(shù)據(jù) 變量定義和使用不在同一個(gè)源程序中,需要利用PUBLIC、EXTREN聲明 共享變量傳遞參數(shù),子程序的通用性較差 特別適合在多個(gè)程序段間、尤其在不同的程序模塊間傳遞數(shù)據(jù),例題5-19有符號(hào)十進(jìn)制數(shù)輸出程序-1,算法如下: 首先判斷數(shù)據(jù)是零、正數(shù)或負(fù)數(shù),是零顯示“0”退出; 是負(fù)數(shù),顯示“”,求數(shù)據(jù)的絕對(duì)值; 接著數(shù)據(jù)除以10,余數(shù)加30H轉(zhuǎn)換為ASCII碼壓入堆棧; 重復(fù)第3步,直到商為0結(jié)束; 依次從堆棧彈出各位數(shù)字,進(jìn)行顯示,例題5-19有符號(hào)十進(jìn)制數(shù)輸出程序-2,mov ecx,count mov ebx,0 again:mov eax,ar
43、rayebx*4 mov dtemp,eax;入口參數(shù)存放到共享變量 call dispsid;調(diào)用子程序顯示一個(gè)數(shù)據(jù) inc ebx call dpcrlf;光標(biāo)回車換行 loop again,例題5-19有符號(hào)十進(jìn)制數(shù)輸出程序-3,dispsidproc;顯示有符號(hào)十進(jìn)制數(shù)子程序 push eax;入口參數(shù):共享變量DTEMP push ebx push edx mov eax,dtemp;取出顯示數(shù)據(jù) test eax,eax;判斷數(shù)據(jù)是零、正數(shù)或負(fù)數(shù) jnz dsid1 mov dl,0;是零,顯示“0”后退出 mov ah,2 int 21h jmp dsid5,例題5-19有符號(hào)十
44、進(jìn)制數(shù)輸出程序-4,dsid1:jns dsid2;是負(fù)數(shù),顯示“-” mov ebx,eax;EAX數(shù)據(jù)暫存于EBX mov dl,- mov ah,2 int 21h mov eax,ebx neg eax;數(shù)據(jù)求補(bǔ)(絕對(duì)值),例題5-19有符號(hào)十進(jìn)制數(shù)輸出程序-5,dsid2:mov ebx,10 push bx;10壓入堆棧,作為退出標(biāo)志 dsid3:cmp eax,0;數(shù)據(jù)(商)為零,轉(zhuǎn)向顯示 jz dsid4 sub edx,edx;擴(kuò)展被除數(shù)EDX.EAX div ebx;數(shù)據(jù)除以10:EDX.EAX10 add dl,30h;余數(shù)(09)轉(zhuǎn)換為ASCII碼 push dx;數(shù)據(jù)
45、先低位后高位壓入堆棧 jmp dsid3,例題5-19有符號(hào)十進(jìn)制數(shù)輸出程序-6,dsid4:pop dx;數(shù)據(jù)先高位后低位彈出堆棧 cmp dl,10;是結(jié)束標(biāo)志10,則退出 je dsid5 mov ah,2;進(jìn)行顯示 int 21h jmp dsid4 dsid5:pop edx pop ebx pop eax ret;子程序返回 dispsidendp,堆棧傳遞參數(shù),主程序?qū)⑷肟趨?shù)壓入堆棧,子程序從堆棧中取出參數(shù) 子程序?qū)⒊隹趨?shù)壓入堆棧,主程序彈出堆棧取得它們 采用堆棧傳遞參數(shù)是程式化的,它是編譯程序處理參數(shù)傳遞、以及匯編語(yǔ)言與高級(jí)語(yǔ)言混合編程時(shí)的常規(guī)方法,例題5-20計(jì)算有符號(hào)數(shù)
46、平均值程序-1,算法如下: 被加數(shù)進(jìn)行符號(hào)擴(kuò)展 求和 除以數(shù)據(jù)個(gè)數(shù)得到平均值 32位有符號(hào)數(shù)擴(kuò)展到64位,32位表示數(shù)據(jù)個(gè)數(shù)(最大232 ) ,不會(huì)溢出,例題5-20計(jì)算有符號(hào)數(shù)平均值程序-2,mov eax,count push eax;壓入數(shù)據(jù)個(gè)數(shù)(0表示232個(gè)) mov ebx,offset array push ebx;壓入緩沖區(qū)的偏移地址 call mean;調(diào)用子程序,求平均值 add esp,8;平衡堆棧 mov dmed,eax;保存出口參數(shù),例題5-20計(jì)算有符號(hào)數(shù)平均值程序-3,meanproc;計(jì)算有符號(hào)數(shù)平均值 push ebp mov ebp,esp push eb
47、x;保護(hù)寄存器 push ecx push edx push esi push edi mov ebx,ebp+6;從堆棧取偏移地址 mov ecx,ebp+10;從堆棧取數(shù)據(jù)個(gè)數(shù),堆棧示意圖,例題5-20計(jì)算有符號(hào)數(shù)平均值程序-4,xor esi,esi;ESI保存求和的低32位值 mov edi,esi;EDI保存求和的高32位值 mean1:mov eax,ebx;取出一個(gè)數(shù)據(jù)EAX cdq;符號(hào)擴(kuò)展EDX.EAX add esi,eax;求和低32位 adc edi,edx;求和高32位 add ebx,4;指向下一個(gè)數(shù)據(jù) dec ecx;數(shù)據(jù)個(gè)數(shù)減少一個(gè) jnz mean1;循環(huán) m
48、ov eax,esi;累加和在EDX.EAX mov edx,edi,例題5-20計(jì)算有符號(hào)數(shù)平均值程序-5,mov ecx,ebp+10;數(shù)據(jù)個(gè)數(shù)在CX idiv ecx ;有符號(hào)數(shù)除法,EAX平均值(EDX余數(shù)) pop edi;恢復(fù)寄存器 pop esi pop edx pop ecx pop ebx pop ebp ret meanendp,宏匯編,宏(Macro):具有宏名的一段匯編語(yǔ)句序列 宏需要先定義 宏名MACRO 形參表 ;宏定義體 ENDM 然后程序中進(jìn)行宏調(diào)用 宏名 實(shí)體參數(shù) 宏定義體的標(biāo)號(hào)必須用LOCAL偽指令聲明 LOCAL 標(biāo)號(hào)1,標(biāo)號(hào)2,例題5-21十六進(jìn)制數(shù)輸入
49、程序-1,;宏定義 dispmsgmacro message;message是形式參數(shù) push ax push dx mov ah,9 lea dx,message int 21h pop dx pop ax endm,例題5-21十六進(jìn)制數(shù)輸入程序-2,asctohmacro local asctoh1,asctoh2 cmp al,9 jbe asctoh1 ;小于等于9,是09,只需減去30H cmp al,a jb asctoh2 ;大于9小于a,是AF,還要減7 sub al,20h ;大于等于a,是af,再減去20H asctoh2:sub al,7 asctoh1:sub al
50、,30h endm,例題5-21十六進(jìn)制數(shù)輸入程序-3,;數(shù)據(jù)段 msgdb Please input,13,10,$ wvardw ? ;代碼段 dispmsg msg;提示輸入,例題5-21十六進(jìn)制數(shù)輸入程序-4,mov cx,4 mov bx,0;BX保存轉(zhuǎn)換后的結(jié)果 again:mov ah,6;輸入字符但不顯示 mov dl,0ffh int 21h jz again;沒有輸入字符繼續(xù),功能調(diào)用,例題5-21十六進(jìn)制數(shù)輸入程序-5,cmp al,0;測(cè)試是否是合法字符 jb again;沒有輸入合法字符,重新輸入 cmp al,9 jbe next;輸入合法字符就顯示 cmp al,
51、A jb again cmp al,F jbe next cmp al,a jb again cmp al,f ja again;測(cè)試結(jié)束,例題5-21十六進(jìn)制數(shù)輸入程序-6,next:mov ah,6;顯示輸入字符 mov dl,al int 21h asctoh;轉(zhuǎn)換為十六進(jìn)制數(shù) shl bx,4;將上次輸入左移二進(jìn)制4位 add bl,al;加上本次輸入的數(shù)碼 loop again mov wvar,bx,宏展開,宏與子程序,都簡(jiǎn)化源程序的書寫,但有本質(zhì)區(qū)別 宏調(diào)用 在匯編時(shí)復(fù)制宏定義語(yǔ)句 執(zhí)行時(shí)不存在控制的轉(zhuǎn)移與返回 沒有減少匯編后的目標(biāo)代碼 執(zhí)行速度也沒有改變 子程序調(diào)用 在執(zhí)行時(shí)控制轉(zhuǎn)移到子程序 子程序沒有被復(fù)制,匯編后
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 車輛股權(quán)轉(zhuǎn)讓與改裝升級(jí)服務(wù)合同
- 出租車司機(jī)聘用及服務(wù)質(zhì)量保障合同
- 項(xiàng)目中止后采購(gòu)合同數(shù)量變更及取消協(xié)議
- 老妖精咨詢工程師課件
- 美術(shù)紅色文化課件設(shè)計(jì)
- 安全生產(chǎn)方針五要素
- 物業(yè)消防工作計(jì)劃
- 安全生產(chǎn)管理制度及處罰條例
- 水電安全操作規(guī)程
- 安全生產(chǎn)提升活動(dòng)總結(jié)
- 辦公室副主任考試試題及答案詳解
- 克拉瑪依市公安局招聘警務(wù)輔助人員考試真題2024
- 2024年石家莊市市屬國(guó)有企業(yè)招聘考試真題
- 醫(yī)院火災(zāi)的應(yīng)急預(yù)案及處理流程
- 醫(yī)院呼吸機(jī)操作評(píng)分表
- 2025年天津市河北區(qū)普通高中學(xué)業(yè)水平合格性模擬檢測(cè)數(shù)學(xué)試題(含答案)
- 2025-2030中國(guó)物理氣相沉積(PVD)涂層系統(tǒng)行業(yè)市場(chǎng)發(fā)展趨勢(shì)與前景展望戰(zhàn)略研究報(bào)告
- 2025河南省豫地科技集團(tuán)社會(huì)招聘169人筆試參考題庫(kù)附帶答案詳解
- 人教版(2024)七年級(jí)下冊(cè)英語(yǔ)期末模擬測(cè)試卷(含答案)
- 兵團(tuán)開放大學(xué)2025年春季《公共關(guān)系學(xué)》終結(jié)考試答案
- 電線電纜出入庫(kù)管理制度
評(píng)論
0/150
提交評(píng)論