lab5 编写调试具有多段的程序
(1)
代码:
assume cs:code,ds:data,ss:stack
data segment
dw 0123h,0456h,0789h,0abch,0defh,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
上图是程序没有
ds指的是整个代码块加载的地方
很好理解, PSP 会用 100H 的内存, 然后先是data段, 075a:100 也就是076a, 占 16个字节, 所以 stack 段 在 076a:0010 也就是 076b cs同理
可以看到, 程序中的三个段在物理上是连续的内存
(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
①data段中的数据没有发生变化
②cs = 076c
ss = 076b
ds = 076a
ds’’ = 075a
③ cs -2h
cs - 1h
④ 如果段中有n个字节, 则程序加载后, 该段的实际占有空间大小为
这道题里 data 和 stack 段明明只有 4 字节却分配了 16 字节的空间大小
所以分配的一定是 n 和 16的最小公倍数
(3)
代码:
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
① 没变
② ds 076d
ss 076e
cs 076a
可以看到 这种代码下 cs 在物理地地址中在低地址, 并且大小是 32 字节 0020h
③ ds: cs + 2h
ss: cs + 3h
(4)
从第一个段开始 分别是 data data code
因为默认情况下 Cs 的值是 ds + 0010h
(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 ax,b
mov es,ax
mov ax,c
mov ss,ax
mov bx,0
mov cx,8
s: mov al,ds:[bx]
mov ss:[bx],al
mov ah,es:[bx]
add ss:[bx],ah
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
这题小总结一下:
这里分别用 ds es ss 三个段寄存器 去存了 abc 三个段的值
然后需要注意的是, db 伪指令定义的数据大小是一字节
所以后面用 al ah 两个中间量去存 ds:[bx] 和 es:[bx] 里的字节对应的值
还有一个教训:
只要加法就去思考是不是会涉及到overflow
注意相加的两个数和要操作的数的大小(位上)
这道题做这么久, 明显看出我汇编水平的拉胯, 汇编程序太生疏了, 确实, 汇编从逻辑上确实比高级语言难操作的多
(6)
用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,16
mov cx,8
mov bx,0
s: push ds:[bx]
inc bx
inc bx
loop s
mov ax,4c00h
int 21h
code ends
end start
这里记录两点:
bx加的时候注意是字为单位还是字节, 第一次 Bx只加了1 导致结果很怪
第二点, 为什么高位在低字节?
我想想
为了验证我先去未执行的 a段瞧瞧
看了之后我懂了, 我多少带点
在DOS的指令里从左往右是增高地址, 所以是正确的…