三个非常重要的实验
-
assume cs:code, ds:data, ss:stack data segment dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987 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
(1). CPU执行程序,程序返回前,data段中的数据为多少?不变
(2). CPU执行程序,程序返回前,cs = 076C、ss = 076B、ds = 076A。
(3). 设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
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). CPU执行程序,程序返回前,data段中的数据为多少?不变
(2). CPU执行程序,程序返回前,cs = 076C、ss = 076B、ds = 076A。
(3). 设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1
(4). 对于如下定义的段:
name segment
……
name ends
如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为(N/16 +1)*16。
必为16的整数倍。
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 0h, 0h
stack ends
end start
(1). CPU执行程序,程序返回前,data段中的数据为多少?不变
(2). CPU执行程序,程序返回前,cs = 076A、ss = 076E、ds = 076D。
(3). 设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4
(4). 如果将前三题中的最后一条伪指令改为end,也就是说,不指明程序的入口,则哪个程序仍然可以正确执行?
都可以,编译缺省的认为程序段的第一条指令为入口。
(5)将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 bx, 0
mov cx, 8
mov ax, 0
s: add al, [bx]
add al, [bx+10h]
mov [bx+20h], al
inc bx
mov ax, 0
loop s
mov ax, 4c00h
int 21h
code ends
end start
可以看到第1行+第2行=第3行。
(6) 用push指令将a段中的前8个字型数据,逆序存储到b段中
思路:将b段当作栈段,把a的数据一个个放入即可。正好从栈底(高地址)到栈顶(低地址)。
assume cs:code
a segment
db 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, b
mov ss, ax
mov sp, 10h
mov ax, a
mov ds, ax
mov cx, 8
mov bx, 0
s: push [bx]
add bx, 2
loop s
mov ax, 4c00h
int 21h
code ends
end start
可以看出第三行是倒序的。注意这个倒序是按字来的,不是字节。它们是一个整体。两个16进制数表示一个字节。
第一行应该理解为:0001,0002而不是0100,0200,第三行也是0008,0007。
通过这三个实验可以知道,如果段中的数据占N个字节,则程序加载后,该段实际占有的空间为(N/16+1)*16。简单来说,如果有数据就一定是16的倍数大小的内存分配,不够一次就分配16个字节的内存。
而且它们的各个段的内存地址位置也由它们定义的先后来决定。