在匯編源程序中,數(shù)據(jù)不能以字母開(kāi)頭,故要加0識(shí)別!
debug程序開(kāi)始時(shí)DS指向的是PSP的頭地址,而CS=DS+10H
不能將一個(gè)數(shù)值直接送入段寄存器,要通過(guò)其它寄存器進(jìn)行傳送!
(N/16+1)*16 意思是總?cè)《?6個(gè)字節(jié)存放多出的字節(jié).N+16不等價(jià)左邊的式子.
它等價(jià)于(int(N/16)+1).
一般來(lái)說(shuō),當(dāng)我們要暫存數(shù)據(jù)時(shí),都應(yīng)該使用棧!
(1)只有bx,si,di,bp用在[]里進(jìn)行內(nèi)在單元的存取.
(2)bx,si,di,bp只能以bx與si,bx與di,bp與si,bp與di四種組合出現(xiàn)
形像些:
si
/
bx
\
di
si
/
bp
\
di
(3)只要在[]中使用寄存器bp,而指令中沒(méi)有顯性地給出段地址,段地址就默認(rèn)在ss中,其它的 是不是默認(rèn)存放在ds中?
數(shù)據(jù)處理的分類(lèi):寫(xiě)入,讀取,運(yùn)算!
數(shù)據(jù)存在的三個(gè)地方:CPU內(nèi),內(nèi)存,端口!
push只進(jìn)行字操作,pop呢?
用dd定義的數(shù)的存放,如100001它的十六進(jìn)制為186A1H,則它在內(nèi)存的存放形式是
A1 86 01 00
剛剛好是32位,和我們的邏輯000186A1不一樣(規(guī)律:倒過(guò)來(lái)).
在一個(gè)數(shù)據(jù)段里定義的數(shù)據(jù)是連續(xù)存放的,但要看清楚它們是什么類(lèi)型(dd,dw,db).
db '1634'里面一個(gè)字符占一個(gè)字節(jié),保存的是相應(yīng)的ACSII碼.
loop指令是先把CX寄存器的值減1然后再判斷是否是0
assume cs:code
code segment
mov ax,4c00H
int 21H
start: mov ax,0
s: nop
nop
mov di,offset s ;以下四行復(fù)制s2的第一條指令給s
mov si,offset s2 ;剛剛好覆蓋了s的兩條nop指令
mov ax,cs:[si] ;復(fù)制過(guò)去的內(nèi)容是:"向前或向后移動(dòng)多少"
mov cs:[di],ax
s0: jmp short s
s1: mov ax,0
int 21H
mov ax,0
s2: jmp short s1 ;機(jī)器碼EBF6;意思是"向前移動(dòng)10d個(gè)字節(jié)"
nop
code ends
end start
;9D:0000 B8004C MOV AX,4C00
;9D:0003 CD21 INT 21
;9D:0005 B80000 MOV AX,0000
;9D:0008 EBF6 JMP 0000 EBF6復(fù)制過(guò)來(lái)后前移10個(gè)字節(jié)即跳到0000
;9D:000A BF0800 MOV DI,0008
;9D:000D BE2000 MOV SI,0020
;9D:0010 2E CS:
;9D:0011 8B04 MOV AX,[SI]
;9D:0013 2E CS:
;9D:0014 8905 MOV [DI],AX
;9D:0016 EBF0 JMP 0008
;9D:0018 B80000 MOV AX,0000
;9D:001B CD21 INT 21
;9D:001D B80000 MOV AX,0000
對(duì)call指令的一些理解:
call word ptr 內(nèi)存單元地址
書(shū)上理解:
push IP
jmp word ptr 內(nèi)存單元地址
我的理解:
(1)IP的值先變成CALL指令后的第一個(gè)字節(jié)的偏移地址,然后才被壓入棧;
(2)壓入后再改變IP的值,即(IP)=內(nèi)存單元地址的值.
call dword ptr 內(nèi)存單元地址
書(shū)上理解:
push cs
push ip
jmp dword ptr 內(nèi)存單元地址
開(kāi)始是將此時(shí)的CS,IP(IP應(yīng)該是CALL命令后的第一個(gè)字節(jié))壓入棧,CS是先壓入錢(qián)的,
然后跳到內(nèi)存單元中內(nèi)容所指的地址,
即CS=((內(nèi)存單元地址)+2),IP=(內(nèi)存單元)//其實(shí)這兩個(gè)是JMP指令的理解.
對(duì)X/N=int(H/N)*65536+(rem(H/N)*65536+L)/N的理解
int(H/N)*65536求出的是高16位的值,即 16位的值0000
后面16位是低16位的值,因?yàn)楹竺娴纳滩粫?huì)超過(guò)16位,求出的商就是低16的值,加到0000上
而(rem(H/N)*65536+L)/N算得的余數(shù)就是本X/N的余數(shù).
注意*65536的含義是向左移多少位,后面的補(bǔ)零.
先算16進(jìn)制再算十進(jìn)制!
int是將子程序裝入內(nèi)在先,然后通過(guò)代號(hào)進(jìn)行調(diào)用.(靜態(tài))
而call就如動(dòng)態(tài)執(zhí)行這樣,等到運(yùn)行時(shí)才裝入內(nèi)存.(動(dòng)態(tài))
P246的中斷例程的理解
lp:push bp ;此時(shí)棧里的情況是:bp ip cs 標(biāo)志寄存器
mov bp,sp
dec cx
jcxz lpret
add [bp+2],bx ;因?yàn)閎p默認(rèn)的段寄存器是ss,故使用了bp,而+2就指向了ip的值.
lpret:
pop bp
iret ;由cx 來(lái)決定是循環(huán)還是向下繼續(xù)執(zhí)行,
編寫(xiě)中斷例程的步聚:
(1)先將代碼復(fù)制到指定的位置,注意這里要指出要復(fù)制字節(jié)的長(zhǎng)度
(2)再把指定的代碼存放位置放到向量表中,因?yàn)槭峭ㄟ^(guò)向量表進(jìn)行訪問(wèn)的.
(3)你可以編寫(xiě)你的中斷例程了!記得開(kāi)始與結(jié)尾標(biāo)志!
在in與out指令中,只能使用ax或al來(lái)存放從端口中讀入的數(shù)據(jù)或要發(fā)送到端口中的數(shù)據(jù),訪問(wèn)8位端口時(shí)用AL,訪問(wèn)16位端口時(shí)要用AX.
shl,shr指令移位多于一位時(shí)一定要將移的位數(shù)放在cl里.
BCD碼4位確定一個(gè)數(shù),如26的BCD碼為0010 0110
7.8 已知對(duì)應(yīng)于中斷類(lèi)型碼為18H的中斷服務(wù)程序存放在0020H:6314H開(kāi)始的內(nèi)存區(qū)域中,求對(duì)應(yīng)于18H類(lèi)型碼的中斷向量存放位置和內(nèi)容。
在編寫(xiě)程序時(shí),為什么通常總要用STI和CLI中斷指令來(lái)設(shè)置中斷允許標(biāo)志?8259A的中斷屏蔽寄存器IMR和中斷允許標(biāo)志IF有什么區(qū)別?
【解答】偏移地址EA=18H×4=60H,18H中斷向量在中斷向量表中的入口地址為00000H+60H=00060H。中斷服務(wù)程序存放在0020H:6314H開(kāi)始的內(nèi)存區(qū)域中,所以(00060H)=0020H,(00061H)= 6314H。
IF是8086微處理器內(nèi)部標(biāo)志寄存器Flags的中斷允許標(biāo)志位。若IF=1,則CPU可以接受中斷請(qǐng)求;若IF=0,8086就不接受外部可屏蔽中斷請(qǐng)求INTR引線上的請(qǐng)求信號(hào)。在編寫(xiě)程序時(shí),用STI指令使中斷允許標(biāo)志位IF=1,目的是使CPU能夠接受中斷請(qǐng)求,或?qū)崿F(xiàn)中斷嵌套。而用CLI指令使中斷允許標(biāo)志位IF=0,則可以關(guān)中斷,使CPU拒絕接受外部中斷請(qǐng)求信號(hào)。
如果8259A的中斷屏蔽寄存器IMR中的某位為1,就把這一位對(duì)應(yīng)的中斷請(qǐng)求輸入信號(hào)IR屏蔽掉,無(wú)法被8259A處理,也無(wú)法向8086處理器產(chǎn)生INTR請(qǐng)求。
注意:在后面加有":"的地址標(biāo)號(hào),只能在代碼段中使用,不能在其他段中使用.
$表示的是本行地址,
$$則表示開(kāi)始匯編的地址.
2.3總結(jié):
執(zhí)行mov指令不改變CS寄存器
執(zhí)行jmp 段地址:偏移地址 改變CS和IP
執(zhí)行jmp 寄存器 只改變IP不改變CS
實(shí)驗(yàn)五總結(jié):
還沒(méi)加載程序前:
CS:IP指向程序段的第一條指令,故CS可以知道.
SS=CS-2
DS=SS-10H ;這個(gè)知道有沒(méi)有用?
加載后:
SS=CS-1;
DS=CS-2;