第六章 包含多个段的程序
从规范角度来讲,我们不应该随意决定使用内存的哪段空间,而应该由系统为我们分配。因此我们可以在程序中定义数据,这样数据就会被包含在编译连接在可执行文件中,也会被载入内存。数据也就获得了存储空间。
dw 0123h,0456h,0789h
dw为define word,定义字型数据(并开辟内存空间)。用dw定义的数据位于代码段的最开始处,即偏移地址为0. 将程序载入内存后,可以看到代码段最前面存储的是数据,数据之后才是汇编指令。为了让系统知道从哪里开始执行,可以加上start标号,如下。
start标号意味着代码从偏移地址10H(数据占了8个字节)位置开始,这个伪指令会被载入可执行文件的描述信息中,从而被CPU读取并设置CS:IP。因此我们可以这样安排程序框架:
assume cs:code
code segment
...数据...
start:
...代码...
code ends
end start
检测点6.1
- mov cs:[bx], ax
- cs
24h
pop cs:[bx]
用多个段存放数据、栈、代码:
assume cs:code, ds:data, ss:stack
data segment
...
data ends
stack segment
...
stack ends
code segment
start:
mov ax,stack
mov ss,ax
...
mov ax,data
mov ds,ax
...
code ends
end start
人为定义的不同段名,每一个段名都对应一个段地址。
mov ax,stack 将名称为stack的段的段地址送入ax。
assume … 是伪指令,并不会让CPU将cs指向code,ds指向data,ss指向stack。
end start 指明了程序的入口,这个入口将被写入可执行文件的描述信息。可执行文件被载入内存后,cs:ip指向这个入口,开始执行start标号后的指令。
实验5
(1)①data中数据不变
②076C,076B,076A(答案不唯一)
③X-2,X-1
(2)①data中数据不变
②076C,076B,076A(答案不唯一)
③X-2,X-1
④((N-1)/16+1)*16个字节
(3)①data中数据不变
②076A,076E,076D(答案不唯一)
③X+3,X+4
(4)程序3. 在不指明入口的情况下,默认从上至下执行,只有3的代码段位于最开始,可以正常执行。
(5)
mov ax,a
mov ds,ax
mov ax,b
mov es,ax
mov ax,c
mov ss,ax
mov bx,0
mov cx,8
s: mov al,[bx]
add al,es:[bx]
mov ss:[bx],al
inc bx
loop s
mov ax,4c00h
int 21h
(6)
mov ax,a
mov ds,ax
mov ax,b
mov ss,ax
mov sp,16
mov bx,0
mov cx,8
s: push [bx]
add bx,2
loop s
mov ax,4c00h
int 21h