(5)html
這道題的寄存器會不夠,咱們採起入棧出棧的方式來反覆利用寄存器,這裏的1,2,3定義的db,應該是"define byte",字節型數據數組
assume cs:code a segment db 1,2,3,4,5,6,7,8 a ends b segment db 1,2,3,4,5,6,7,8 b ends c segment db 0,0,0,0,0,0,0,0 c ends code segment start: mov ax,a ;a段地址 mov ds,ax mov ax,b ;b段地址 mov es,ax mov cx,8 ;循環次數 mov bx,0 ;交換數據的偏移地址 mov ax,0 ;臨時儲存a+b的數據 s: mov al,es:[bx] add al,[bx] push ds ;ds入棧(這兩處入棧至關於找了個地方,保存以前ds,bx的值) push bx ;bx入棧 mov bx,c ;c段地址 mov ds,bx pop bx ;取出bx mov [bx],al ;將a+b之和賦值給對應的c段地址數據 pop ds ;ds出棧,ds保存a段段地址 inc bx ;偏移地址+1 loop s mov ax,4c00h int 21h code ends end start
(6)oop
先將a段數據入棧,再出棧,儲存到b段對於位置spa
DS=075AH,因此程序入口地址在076AH,根據程序的代碼,咱們知道先a段,再b段,a段佔16字,32字節(1f),因此076A:0H~076A:1FH都是a段數據,b段佔8字,16字節,因此b段在076C:0H~076C:FH3d
assume cs:code a segment dw 1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh a ends b segment dw 0,0,0,0,0,0,0,0 b ends code segment start: mov ax,a mov ds,ax mov ax,b mov es,ax mov bx,0 mov cx,8 s0: mov ax,[bx] push ax add bx,2 loop s0 mov bx,0 s1: pop ax mov es:[bx],ax add bx,2 loop s1 mov ax,4c00h int 21h code ends end start
強烈建議先去把8.1~8.4看了,由於你在這章寫代碼踩的,有關[...]的坑,在8.1~8.4都有說明code
(1)and指令:邏輯與指令,按位進行與運算htm
mov al,01100011B
and al,00111011B
(2)or指令...blog
mov al,01100011B
or al,00111011B
assume cs:codesg,ds:datasg datasg segment db 'BaSiC' db 'iNfOrMaTiOn' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov cx,5 mov bx,0 mov al,11011111b s: and ds:[bx],al inc bx loop s mov cx,11 mov bx,0 mov al,00100000b s0: or ds:[bx],al inc bx loop s0 mov ax,4c00h int 21h codesg ends end start
指令內存
mov ax,[bx,200] ;(ax) = ( (ds) * 16 + (bx) + 200)
等於get
mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200
問題 7.1
(ax)=00beh
(bx)=1000h
(cx)=0606h
assume cs:codesg,ds:datasg datasg segment db 'BaSiC' db 'MinIX' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov cx,5 mov bx,0 s: mov al,11011111b and ds:[bx],al mov al,00100000b or ds:5[bx],al inc bx loop s mov ax,4c00h int 21h codesg ends end start
si和di是8086CPU中和bx功能相近的寄存器si和di不能分紅兩個8位寄存器
mov bx,0 mov ax,[bx] mov si,0 mov ax,[si] mov di,0 mov ax,[di]
問題 7.2
書上代碼:
assume cs:codesg,ds:datasg datasg segment db 'welcome to masm!' db '................' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov di,16 mov cx,8 s: mov ax,[si] mov [di],ax add si,2 add di,2 loop s mov ax,4c00h int 21h codesg ends end start
寫的:
assume cs:codesg,ds:datasg datasg segment db 'welcome to masm!' db '................' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov cx,16 s: mov al,[si] mov [si+16],al inc si loop s mov ax,4c00h int 21h codesg ends end start
不能直接給段寄存器賦值,要使用普通寄存器,不能給段存儲器:[偏移地址]使用直接賦值或者段寄存器賦值,這和前面的段寄存器同樣的。
問題 7.3
和本身寫的7.2同樣
[bx+si]也能夠寫成[bx][si]
mov ax,[bx+si]
mov ax,[bx][si]
問題 7.4
(ax)=00BEH
(bx)=1000H
(cx)=0606H
mov ax,[bx+200+si] mov ax,[200+bx+si] mov ax,200[bx][si] mov ax,[bx].200[si] mov ax,[bx][si].200
問題 7.5
ax=0006h
cx=6a00h
bx=226ah
問題 7.6
開頭字母都在偏移地址3
assume cs:codesg,ds:datasg datasg segment db '1. file ' db '2. edit ' db '3. search ' db '4. view ' db '5. options ' db '6. help ' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov si,3 mov cx,6 mov al,11011111b s: and [si],al add si,10h loop s mov ax,4c00h int 21h codesg ends end start
問題 7.7
assume cs:codesg,ds:datasg datasg segment db 'ibm ' db 'dec ' db 'var ' db 'vec ' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov cx,4 s0: mov dx,cx mov bx,0 mov cx,3 s: mov al,11011111b and [bx+si],al inc bx loop s add si,10h mov cx,dx loop s0 mov ax,4c00h int 21h codesg ends end start
在上面的程序中,使用dx來臨時儲存外層循環cx的值,若是寄存器不夠怎麼辦?兩種方法
1.入棧出棧
assume cs:codesg,ds:datasg datasg segment db 'ibm ' db 'dec ' db 'var ' db 'vec ' datasg ends codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov cx,4 s0: push cx mov bx,0 mov cx,3 s: mov al,11011111b and [bx+si],al inc bx loop s add si,10h pop cx loop s0 mov ax,4c00h int 21h codesg ends end start
上面這個是本身寫的,雖然可以得出正確答案,可是最好定一個棧空間
assume cs:codesg,ds:datasg,ss:stacksg datasg segment db 'ibm ' db 'dec ' db 'var ' db 'vec ' datasg ends stacksg segment dw 0,0,0,0,0,0,0,0 stacksg ends codesg segment start: mov ax,datasg mov ds,ax mov ax,stacksg mov sp,15 mov ss,ax mov si,0 mov cx,4 s0: push cx mov bx,0 mov cx,3 s: mov al,11011111b and [bx+si],al inc bx loop s add si,10h pop cx loop s0 mov ax,4c00h int 21h codesg ends end start
第二種,cx放入內存空間
assume cs:codesg,ds:datasg datasg segment db 'ibm ' db 'dec ' db 'var ' db 'vec ' dw 0 ;有段空間才能使用 datasg ends codesg segment start: mov ax,datasg mov ds,ax mov si,0 mov cx,4 s0: mov ds:[40h],cx ;必須加上ds mov bx,0 mov cx,3 s: mov al,11011111b and [bx+si],al inc bx loop s add si,10h mov cx,ds:[40h] ;必須加上ds loop s0 mov ax,4c00h int 21h codesg ends end start
爲何在[40h]必須加上ds,否則運行失敗?
由於在這裏,咱們使用另外一個段寄存器來儲存cx數據,而使用[40h]默認是ds段寄存器的地址,但咱們儲存cx的段寄存器不必定是ds,能夠命名其餘的,因此須要加上。(見 8.3-(3) ))
問題 7.9
SI源變址寄存器,DI目地變址寄存器,二者不能同時在[...]中使用,具體看點擊1--點擊2
assume cs:codesg,ds:codesg datasg segment db '1. display ' db '2. brows ' db '3. replace ' db '4. modify ' dw 0 datasg ends codesg segment start: mov ax,datasg mov ds,ax mov bx,0 mov cx,4 s0: mov ds:[40],cx mov di,3 ;注意開始位置 mov cx,4 s: mov al,11011111b and [bx+di],al inc di loop s add bx,10h mov cx,ds:[40h] loop s0 mov ax,4c00h int 21h codesg ends end start
前面已作
reg(寄存器):ax, bx, cx, dx, ah, al, bh, bl, ch, cl, dh, dl, sp, bp, si, di;
sreg(段寄存器): ds, ss, cs, es;
http://www.javashuo.com/article/p-nqsdswxn-dc.html
機器指令進行數據處理:讀取,寫入,運算
指令執行前,數據可存在於:CPU內部,內存,端口
機器碼 | 彙編指令 | 指令執行前數據的位置 |
8E1E0000 | mov bx,[0] | 內存,ds:0單元 |
89C3 | mov bx,ax | CPU內部,ax寄存器 |
BB0100 | mov bx,1 | CPU內部,指令緩衝器 |
(1)當即數
直接包含在機器指令的數據(執行前在CPU的指令緩衝器)
mov ax,1
add ax,5
or ax,00100000b
mov bl,'a'
(2)寄存器
指令要處理的數據在寄存器中,也就是給出寄存器
mov ax,bx
mov ds,ax
push bx
mov ds:[0],bx
push ds
mov ss,ax
mov sp,ax
(3)段地址(SA)和偏移地址(EA)
指令要處理在內存中的數據,能夠用[X]的指令給出EA,SA在某個段寄存器中
段地址默認在ds中的
mov ax,[0]
mov ax,[di]
mov ax,[bx+di+8]
段地址默認在ss中的
mov ax,[bp]
mov ax,[bp+8]
mov ax,[bp+si+8]
顯性給出段寄存器地址
mov ax,ds:[bp]
mov ax,es:[bx]
mov ax,ss:[bx+si]
mov ax,cs:[bx+si+8]