Article Directory
6.1 Using data in the code segment
考虑这样一个问题,编程计算以下8个数据的和,结果存在ax寄存器中:
0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H。
(前面的章节是累加某些内存单元中的数据,并不关心数据本身。这个问题是要累加已经给定了数值的数据。)
assume cs:codesg
codesg segment
dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H
mov bx,0
mov ax,0
mov cx,8
s: add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end
"dw"含义是定义字型数据,即define word
在这里,我们使用dw定义了8个字型数据(数据之间以逗号分隔),它们所占的内存空间的大小为16个字节。
用dw定义的数据处于代码段的最开始,所以偏移地址为0,2,4,6,8,A,C,E处。
assume cs:codesg
codesg segment
dw 0123H,0456H,0789H,0abcH,0defH,0fedH,0cbaH,0987H
start: mov bx,0
mov ax,0
mov cx,8
s: add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
end作用:
end除了通知编译器程序结束外,还可以通知编译器程序的入口在什么地方。
6.2 Use stack code segment
完成下面的程序,利用栈,将程序中定义的数据逆序存放。
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h ;定义字型数据
?
code ends
end
程序思路:
程序运行时,定义的数据存放在cs:0~cs:15单元中,共8个字单元。
依次将这8个字单元中的数据入栈,然后再依次出栈到这8个字单元中,从而实现数据的逆序存放。
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0
start:mov ax,cs
mov ss,ax
mov sp,32
mov bx,0
mov cx,8
s:push cs:[bx]
add bx,2
loop s
mov bx,0
mov cx,8
s0:pop cs:[bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
codesg ends
end start
Checkpoint 6.1
(1) The following procedures successively implemented 0: the content of the memory unit 15 data rewriting program: 0~0
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;填空地址,dw对应地址为cs:从0到定义数量*2,将ds:[bx]的数覆盖dw
add bx,2
loop s
mov ax,4c00H
int 21h
codesg ends
end start
(2) The following procedures successively implemented 0: 0 to 0: 15 of the memory cell content rewriting data program, by transmitting data to the stack, the stack space is provided in the program.
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 # 10个字单元用作栈空间
start: mov ax,cs # 定义代码段
mov ss,ax # 定义栈段
mov sp,24h # 定义栈底为24h (hex(8*2 + 10*2))
mov ax,0
mov ds,ax # 定义内存起始段
mov bx,0 # 定义内存偏移
mov cx,8
s: push [bx] # 将ds:[bx]内存单元中的数据写入栈单元ss:sp(sp=24h) -> sp=24h - 2h = 22h
pop cs:[bx] # 将ss:sp(sp=22h)为栈顶的字单元中的数据写入cs:[bx]中 -> sp=22h + 2h = 24h
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
6.3 the data, code, stack into different segments
- The same data and code into a segment, making the program seem confusing
- If the data stack and the space required for the code than 64KB, can not be placed in a segment (a segment can not exceed the capacity of 64KB, we limit in 8086 is used in the learning mode, so not all processors)
How to solve?
- We define and use the same method of code segments defining a plurality of segments, and which defines the data required in the segments, or by defining the stack space to obtain data.
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,0,0,0,0,0,0,0,0
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,20h
mov ax,data
mov ds,ax
mov bx,0
mov cx,8
s:push [bx]
add bx,2
loop s
mov bx,0
mov cx,8
s0:pop [bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
说明:
1.我们在源程序中为这三个段起了具有含义的名称。
用来存放数据的段我们将其命名为"data",用来存放代码的段我们将其命名为"code",用来作栈空间的命名为"stack"
2.assume是伪指令,是由编译器执行的。
How CPU executes the program?
我们在源程序的最后用"end start"说明了程序的入口。
这个入口将被写入可执行文件的描述信息,可执行文件中的程序被加载如内存后,
CPU的CS:IP被设置指向这个入口,从而开始执行程序中的第一条指令。
标号"start"在"code"段中,这样CPU就将code段中的内容当作指令来执行了。
我们在code段中,使用指令:
mov ax,stack
mov ss,ax
mov sp,16
设置ss指向stack,设置ss:sp指向stack:16,CPU执行这些指令后,将把stack段当作栈空间来用。