P121頁
實驗四
(1)編程,向內存 0:200 ~ 0:23F依次傳送數據0~63(3fh)
assume cs:code
code segment
mov ax,0h
mov ds,ax
mov cx,3fh
mov bx,200h
mov al,0h
s:mov [bx],al
inc bx
inc al
loop s
mov ax,4c00h
int 21h
code ends
end
(3) 將mov sc,4C00H 之前的指令複製到內存0:200處。
assume cs:code
code segment
mov ax,cs //將數據段設置爲 代碼段開始位置
mov ds,ax
mov ax,0020h
mov es,ax
mov bx,0
mov cx ,17h //要複製23個字節
s:mov al,[bx]
mov es:[bx],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end
assume cs:codesg
codemsg segment
dw 0123h,0456h,0789h,0abch,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
start: mov ax,cs
mov ss,ax
mov sp,30h
mov bx,0
mov cx,8
s0:push cs:[bx]
add bx,2h
loop s0
mov bx,0
mov cx,8
s1:pop cs:[bx]
add bx,2
loop s1
codemsg ends
end start
前 16個字節存儲了數據,後面32個字節初始化了00
ip指向了段 0030處 也就是 最後一個 00字節處
將棧底 sp設置在 0030處 棧頂設置在 cs 7e處
將cs指向
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h //數據
dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0//棧空間
start: mov ax,cs
mov ss,ax
mov sp,30h
mov bx,0
mov cx,8
s0:push cs:[bx]
add bx,2h
loop s0
mov bx,0
mov cx,8
s1:pop cs:[bx]
add bx,2
loop s1
codesg ends
end start
當程序 執行完成後 按 字 互換了位置 實現了逆序輸出 如下
檢測點 6.1
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h //數據
start mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s:mov ax,[bx]
mov cs:[bx],ax//改成程序數據 從cs開始
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
程序執行前 vs 程序執行後
數據被改變了 那是因爲讀取了從 0:0 ~ 0:f 數據段處的數據.
(2)
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0
start:
mov ax,cs
mov ss,ax
mov sp,24h
mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s:push [bx]
pop cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
要複製的數據 16個字節
複製前程序數據
成功的把 內存000段處的 錢 16個字節取到.
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
data ends
stack segment
dw 0,0,0,0,0,0,0,0
stack ends
code segment
start:mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax,4c00h
int 21h
code ends
end start
程序返回前data段的數據不變
- cs = 07e4 ss= 07e2 ds = 07d2 注意 這裏每個段 是 16個字節 07d2 和07e2 相差一個段 16個字節
程序加載後 假設cs段x data段 x+18 stack段 x + 2
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h
data ends
stack segment
dw 0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax,4c00h
int 21h
code ends
end start
- 1 程序執行前 data段數據
(1)執行後 數據段內容也不會發生改變
(2)CPU執行程序,程序返回前,cs=07e4,ss=07e3 ,ds=07e2
(3)程序加載後,code段地址設爲X,則data段地址爲(x-2),stack段的段地址爲(X-1).
如果段中數據位N個字節,程序加載後,該段實際佔據空間爲(N/16+1) * 16 Byte。
assume cs:code,ds:data,ss:stack
code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
push ds:[0]
push ds:[2]
pop ds:[2]
pop ds:[0]
mov ax,4c00h
int 21h
code ends
data segment
dw 0123h,0456h
data ends
stack segment
dw 0,0
stack ends
end start
這裏棧的定義順序發生了變化,可以觀察如果定義順序發生了變化,棧地址揮發神什麼樣的變化。
- 執行返回前 數據區的數據未發生改變。
2.執行返回前 ,DS:07E5 SS:07E6 CS:07E2
3.程序加載後,code段地址設爲X,則data段地址爲(x+3),stack段的段地址爲(X+4).
4、如果不指名start入口,並且使用end替換end start,程序仍然可以執行。因爲如果不指名入口,程序則從加載進內存的第一個單元起開始執行,但因爲程序中有部分是作爲數據使用的,如果不指明入口,CPU會把這些數值數據當成彙編指令執行,因此有必要通過start來指明入口。
5、編寫code段中的代碼,將a段和b段數據依次相加,結果存入c段
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
mov ds,ax
mov ax,b
mov ss,ax
mov ax,c
mov es,ax
mov bx,0
mov cx,8
s:
mov al,ds:[bx]
add al,ss:[bx]
mov es:[bx],al
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
可以看到 相差了一個段 16個字節的2份內容
進行計算後,讓我們看看結果.
6.編寫code段中代碼,用push指令將a段中前8個字型數據逆序存儲到b段中。
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 ss,ax
mov sp,10h
mov bx,0
mov cx,8
s:
push ds:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end start
要被壓入的棧
壓入後 。。。