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
要被压入的栈
压入后 。。。