第七章知識彙總
第7章 更靈活地定義記憶體地址的方法
7.1 and和or指令
(1)and指令:邏輯與指令,按位進行與運算(相當於將某一位或幾位的值變為0)
例如:mov al,01100011B
and al,00111011B
執行後 al=00100011B
(2)or指令:邏輯或指令,按位進行或運算(相當於將某一位或幾位的值變為1)
例如:mov al,01100011B
or al,00111011B
執行後:al=01111011B
7.2 關於ASCII碼
我們的操作————轉換為ASCII碼—————寫入指定記憶體空間————轉換成我們想要的效果
7.3以字元形式給出的資料
在彙編程式中,我們用'......'的方式來指明資料是以字元形式給出的
我們以下面的程式為例:
assume cs:code,ds:data
data segment
db 'unIX'
db 'foRX'
data ends
code segment
start:mov al,'a'
mov bl,'b'
mov ax,4c00h
int 21h
codesg ends
end start
這裡對上述程式碼做幾點解釋:
(1)db 'foRK' 相當於“db 75H,6EH,49H,58H”
PS:和 dw做一下比較
(2)mov ax,'a'相當於mov ax,61H
在debug中可以用r命令先分析一下data的地址,然後可以用d命令來檢視段中的16進位制的數碼和對應的ASCII碼
7.4大小寫轉換的問題
我們考慮這樣一個問題,在codesg中填寫程式碼。將datasg中的一個字串轉換為大寫,第二個字串轉換為小寫
小寫字母的ASCII碼比其對應的大寫字母要大20H
那麼轉換為大寫的話,只要將小寫字母對應的數值減去20H就行了;準換為小寫的話就反過來
可是我們又面臨一個問題:如何判斷字母的大小寫?
我們現在沒有學習到可以判斷的指令,但是現階段又要求我們解決此類問題。依照書中思想,我們不妨試試看繞過判斷來解決問題
這就用到了我們前面預先學習的and和or指令
我們發現 大寫與小寫字母的ASCII碼的二進位制形式,差別只在第五位,而大寫字母的第五位為0,小寫字母的第五位為1。因此問題只要合理運用and和or指令就能解決
下面給出解決問題的程式:
assume cs:codesg,ds:datasg
datasg segment
db 'BaSiC'
db 'iNfOrMaTiOn'
datasg ends
codesg segment
start:mov ax,datasg
mov ds,ax
mov bx,0
mov cx,0
s:mov al,[bx]
and al,11011111B
mov [bx],al
inc bx
loop s
;轉換成小寫一次類推
mov ax 4c00h
int 21h
codesg ends
end start
7.5 [bx+idata]
[bx+idata]表示什麼?表示一個記憶體單元,他的偏移地址為(bx)+idata(bx中的數值加上idata),段地址在ds中
[bx+idata]還可以寫成其他形式:[200+bx]
200[bx]
[bx].200
7.6 用[bx+idata]的方式進行陣列的處理
將與陣列一起理解時,要注意一點:idata和c語言中的未知數不同,在數列中,C語言中的未知數是來確定同一陣列中的不同元素的,而idata則是用來定義另一個或多個數組的
7.7 SI和DI
SI和DI是8086CPU中和bx功能相近的暫存器,不同的是SI和DI不能分為兩個8位暫存器來使用
7.8 [bx+si]和[bx+di]
可以用[bx+idata]來幫助理解,
另外 [bx+si]也可以表示為[bx][si]
7.9 [bx+si+idata]和[bx+di+idata]
其他的表示方法:[bx+200+si]
[200+bx+si]
200[bx][si]
[bx].200[si]
[bx][si].200
7.10 不同定址方式的靈活應用
定位記憶體地址的方式,我們稱之為定址方式
有下列幾點發現:
(1)[idata]用一個常量來表示地址,可用於直接定位一個記憶體單元
(2)[bx]用一個變數來表示記憶體地址,可用於間接定位一個記憶體單元
(3)[200+bx]用一個變數和常量來表示地址,可在一個起始地址的基礎上用變數間接定位一個記憶體單元
(4)[bx+si]用兩個變量表示地址
(5)[bx+200+si]用兩個變數和一個常量表示地址。
P152 從這需要認真看到本章實驗