assume cs:code, ds:data data segment db ‘Nuist‘ db 5 dup(2) data ends code segment start: mov ax, data mov ds, ax mov ax, 0b800H mov es, ax mov cx, 5 mov si, 0 mov di, 0f00h s: mov al, [si] and al, 0dfh mov es:[di], al mov al, [5+si] mov es:[di+1], al inc si add di, 2 loop s mov ah, 4ch int 21h code ends end start
每一行代码的含义如下:
mov cx, 5 五次循环 mov si, 0 初始化 si mov di, 0f00h 初始化 di s: mov al, [si] 取数据段内对应字符 and al, 0dfh 将字符改为大写 mov es:[di], al 写入显存 mov al, [5+si] 为 al 赋数据段内的值 mov es:[di+1], al 为先前写入字符的字的高位赋值,以此附以字符颜色 inc si si + 1,移向数据段下一字符 add di, 2 di + 2,移向显存下一个字 loop s 循环执行
使用 masm、link 对 task1.asm 进行汇编、链接,得到可执行文件 task1.exe,运行并观察结果:
使用debug调试工具对程序进行测试,执行到程序返回前,即line27之前,观察结果。
改变data段line4中的值后的结果:
db 5 dup(2)
猜想:这里的作用是改变字符的颜色。
2. 实验任务2
编写 task2.asm
assume cs:code, ds:data data segment db 23,50,66,71,35 data ends code segment start: mov ax,data mov ds,ax mov dh,0ah mov di,0 mov cx,5 s: mov al,[di] mov ah,00h div dh add al,30h add ah,30h mov bx,ax inc di mov ah,2 mov dl,bl int 21h mov dl,bh int 21h mov dl,20h int 21h loop s mov ah,4ch int 21h code ends end start
使用 masm、link 对 task2.asm 进行汇编、链接,得到可执行文件 task2.exe,运行并观察结果:
执行结果:
3. 实验任务3
task3.asm:
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
使用 masm、link 对 task3.asm 进行汇编、链接:
问题 1:程序返回前,data 段中的数据为:
23 01 56 04 89 07 bc 0a ef 0d ed 0f ba 0c 87 09
反汇编:
问题 2:程序返回前,cs、ss、ds 的值为
问题 3:设程序加载后,code 段的段地址为 X, 则 data 段的段地址为 X - 1,stack 段的段地址为 X - 2。
4. 实验任务4
task4.asm:
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 段中的数据为:
23 01 56 04 00 00 00 00 00 00 00 00 00 00 00 00
问题 2:程序返回前,cs、ss、ds 的值为:
cs = 076c ss = 076b ds = 076a
问题 3:设程序加载后,code 段的段地址为 X,
则 data 段的段地址为 X - 1,stack 段的段地址为 X - 2。
问题 4:对于如下定义的段:
name segment
...
name ends
如果段中的数据占 N 个字节,则程序加载后,该段实际占用的空间为: [N/16]*16,
5. 实验任务5
task5.asm:
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
问题 1:程序返回前,data 段中的数据为:
23 01 56 04 00 00 00 00 00 00 00 00 00 00 00 00
问题 2:程序返回前,cs、ss、ds 的值为:
cs = 076A ss = 076E ds = 076D
问题 3:设程序加载后,code 段的段地址为 X, 则 data 段的段地址为 X + 4,stack 段的段地址为 X + 5。
6. 实验任务6
问题:如果将前三题中的最后一条伪指令“end start”改为“end”(也就是说,不指明程序的入口),则哪个程序仍然可以正确执行?请说明原因。
只有第三个程序能够正确执行。
如果将 end start 改为 end,则不指明函数的入口。由于其余程序的 code 段在data 段和 stack 段 之后,如果不指明入口,会默认从 076A:0 开始执行,即将数据段与栈段的数据当作程序运行,所以造成出错;而实验任务 5 的 data 段与 stack 段处于 code 之后,默认执行的起点就是 code 段的内容,所以可以正确执行。
7. 实验任务7
task7.asm:
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 ; 在集成软件环境中,请将此处的段名称由c→改为c1或其它名称
db 8 dup(0)
c ends
code segment
start:
mov ax,a
mov ds,ax
mov si,0
mov cx,4
s: mov ax,[si]
add ax,[si+10h]
mov [si+20h],ax
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start
可得已完成相加。
8. 实验任务8
task8.asm:
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 8 dup(0) b ends code segment start: mov ax,a mov ds,ax mov ax,b mov ss,ax mov sp.16 mov cx,8 s: push [si] add si,2 loop s mov ax,4c00h int 21h code ends end start
1.如果在 code 段前有自己设置的逻辑段,需要指明程序的入口,要加上end start,否则会发生错误。
2.段名代表的是段地址,是常数。不能使用 mov 直接送入段寄存器。
3.各逻辑段在内存空间中依序排列,并以 16 个字为一个单元进行分配
原文:https://www.cnblogs.com/dawn1f/p/14044997.html