实验3 多个段的汇编源程序编写与调试
一、实验目的
1、理解和掌握将数据、代码、栈放入不同逻辑段的程序编写和调试。
2、理解具有多个段的汇编程序对应的目标程序执行时,内存分配方式。
3、掌握大小写字符的转换方法、数字字符和数值之间的转换方法。
4、理解并 掌握各种寻址方式的灵活运用。
5、掌握汇编指令loop,and,or,div,mul的用法
二、实验内容
任务一
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
分析:该源程序在数据段中定义了字数据‘nuist’和5个2。代码段中,借助ax将数据段的地址移入ds,其偏移地址用si表示,初值为0。之后同理,把附加段es寄存器赋值为0b800H ,其偏移地址用di表示,初值为0f00H。
主要功能就是先按顺序读入字数据‘Nuist’的单个字符,全部转换为大写,存入附加段所指示的地址,然后再将ds的偏移地址si加5,把数据段位于‘nuist’之后的数字2移入附加段中刚移入字符的单元的后边,如此循环五次。
单个ASCll码控制显示的字符,紧挨着的数字控制显示的颜色。
db 5 dup(2) --> 改成: db 2,3,4,5,6
任务二
assume cs:code,ds:data data segment db 23, 50, 66, 71, 35 data ends code segment start: mov ax,0810h mov es,ax mov ax,data mov ds,ax mov si,0 mov di,0 mov cx,5 mov ax,0 s: mov al,ds:[si] mov bl,10 div bl add ah,48 add al,48 mov es:[di],al mov es:[di+1],ah add di,2 add si,1 mov ax,0 loop s mov di,0 mov cx,10 p: mov ah,2 mov dl,es:[di] int 21h add di,1 loop p mov ah,4ch int 21h code ends end start
分析:首先,ax置为0,将数据段的数据保存在ax中(注意是字节数据),接着利用除法分割成单个的数字,再利用ascll码性质把单个数字转为单个字符,存入附加段es中,最后通过循环打印到屏幕上,如图。
任务3
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
- data段中的数据:23 01 56 04 89 07 bc 0a ef 0d ed 0f ba 0c 87 09
- 程序返回前,cs=076c,ss=076b,ds=076a
- 设程序加载后,code段的段地址为X,则data段的段地址为:X-2H,stack段的段地址为:X-1H
任务四
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段的数据为:23 01 56 04
- 程序返回前,cs=076c、ss=076b、ds=076a
- code段的段地址为X,则data段的段地址为:X-2H,stack段的段地址为:X-1H
- 对于如下定义的段,name segment ... name ends ,假设占N个字节,则程序加载后实际占有空间为:(1+N/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 0,0 stack ends end start
- 程序返回前,data段的数据为23 01 56 04
- 程序返回前,cs=076a、ss=07de、ds=076d
假设code段的段地址X,则data段的段地址为:X+3H,stack段的段地址为:X+4H
任务六
如果将任务三到任务五的“end start”改为“end”,则哪个程序可以正常执行?
答:任务五的程序仍可以正常执行,因为它的代码段定义在数据段和栈段之前,在程序顺序执行时,不会错误把数据段或栈段识别为代码段执行。
任务七
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 c1 segment db 8 dup(0) c1 ends code segment start: mov ax,a mov es,ax mov ax,c1 mov ds,ax mov si,0 mov cx,8 mov ax,0 s: add ax,es:[si] add ax,es:[si+16] mov ds:[si],ax add si,1 mov ax,0 loop s mov ax,4c00h int 21h code ends end start
任务八
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,b mov ss,ax mov sp,16 mov ax,a mov ds,ax mov si,0 mov cx,8 s: push ds:[si] add si,2 loop s mov ax,4c00h int 21h code ends end start
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫