匯編第四日
段的起始地址總是16的倍數,設段中數據占N字節,那麽段的大小為(N/17+1)/16字節
CPU執行指令(如果end 之後沒有標號的話)默認是從偽代碼後第一行指令開始,有標號後會從用戶指定的指令開始執行
and al, 10111111B:將第6位設置成0,其余位不變
or al, 01000000B:將第4位設置成1,其余位不變
‘ ‘符號來定義字符,例如 db ‘UNIX‘
那麽其在內存中分布情況為:
mov ax, ‘a’ 把a對應的ASCII碼‘61H‘賦值給ax
ASCII編碼的一個字符占1字節,unicode編碼占4字節
[bx+idata]表示有時更方便,例如:
① A,B,C,D,E ② a,b,c,d,e 將①中數據變小寫,②變大寫
如果沒有[bx+idata]寫的話:用兩個循環,一個改成小寫,一個改成大寫
一個循環:
ds:[bx]將A變成a,之後寫成ds:[bx+5]將a變成A
si寄存器和di寄存器類似於bx寄存器,可以保存內存地址,但是前兩者無法分成高低8位
到此,內存單元可以表示成
[ds+si+idata],[bx+si],[bx+idata],[bx].idata,idata[bx],[bx].idata[si]
(寄存器和寄存器)
;用來表達註釋
cx寄存器表達數據範圍為0 - (2^16) - 1 所以一旦0 減去 1後結果會變成FFFFH((2^16) - 1)
對於多層循環,要註意cx寄存器的使用,內層循環會覆蓋掉外層循環的cx寄存器值
解決方法:
進入內層循環前,先將cx數據保存在棧中,等到退出內層循環中,再pop將cx恢復到外層循環狀態
只有bx,bp,si,di用在表示內存單元,配合使用規則:
bx與si , bx與di,bp與si,bp與di 可以配合使用
bx與bp,si與di 均不可以
bp寄存器相當於sp寄存器,對於[bp]這樣表示,那麽默認的段地址在sp寄存器中,但可以顯式指定段前綴:例如ds:[bp],cs:[sp]
對於mov ax,1指令,其中的立即數1,直接反映在該指令對應的機器碼中,對於指令則放在指令緩沖器中
指明處理數據長度:
①寄存器指明 :mov ax, [1]內存偏移地址為1的字型數據,al則為字節型數據
②xxx ptr
mov word ptr ds:[0], 1(1當成字型數據)
mov byte ptr ds:[0], 1(1當成字節數據)
③默認長度
push和pop都是字型數據
對於類似於結構體bx中,idata為結構體中某數據項,si為某數據項為數組中的元素:
那麽定位該元素可以表達成[bx].idata[si] = [bx+idata+si]
div指令執行除法:
①除數為8位,則被除數為16位保存在ax中,結果商放在al中,余數放在ah中
②除數為16位,則被除數為32位保存在dx(高16位)和ax(低16位)中,結果商放在ax中,余數放在dx中
為什麽除數n位,被除數就要2*n位?
因為CPU總是用加法來模擬其他運算,例如乘法2*3用2+2+2模擬,那麽也用乘法模擬除法,例如9/4,4*1 < 9,那麽再用4 * 2 < 9,直到4 * 3 > 9結束,返回前一步,知道結果為2,余數為9 - 2*4 =1,這就要求被除數要比除數大來防止檢驗過程中數據溢出
除法過程:
div bx:除數bx為16位,所以被除數要32位:
(ax) = ((dx)*10000H + (ax))/(bx)的商
(dx) = ((dx)*10000H + (ax))/(bx)的余數
div byte ptr ds:[0]:byte ptr指明除數為8位,所以被除數為16位:
(al) = (ax)/((ds)*16 + 0)的商
(ah) = (ax)/((ds)*16 + 0)的余數
div word ptr ds:[0]:word ptr指明除數為16位,所以被除數為32位:
(ax) = ((dx)*10000H + (ax))/((ds)*16 + 0)的商
(dx) = ((dx)*10000H + (ax))/((ds)*16 + 0)的余數
為什麽dx要乘以10000H?
10000H = 16^4D,在十六進制下,即數據左移4位,後面多出來的4個0剛好給ax內容
dd = define double word(32bit)
實現64位功能條件:64位CPU,64位OS,64位軟件,當中少一項都為32位
dup指令:
db 3 dup(0):定義3字節,且內容都為0
db 4 dup(0,1,2):定義9字節,內容為0,1,2,0,1,2,0,1,2
Done!!!
匯編第四日