本文使用TPC-UPC-ZK集成环境进行汇编语言程序设计
内含
1、内存中现有X和Y两个存储单元,分别存有42和-43,利用汇编语言编程计算这两个数之和,并将结果存入SUM单元
2、数据段中的一个存储单元X中存放的数据为10H,编程实现将该存储单元中的数据循环左移四位后存放到数据段的另一个存储单元Y中
3、编程实现三个四位十六进制数1234H,5678H,AAAAH的相加运算,结果存放在数据段的存储单元SUM中
等题目
付源代码、结果图、流程图等
预习要求:
1、8086系统的各种寻址方式:立即寻址方式* —— 操作数在指令中给出、寄存器寻址方式* —— 操作数在指定的寄存器中、直接寻址方式* —— 有效地址EA由指令直接给出、寄存器间接寻址方式* ——EA在基址寄存器(BX/BP) 或变址寄存器(SI/DI)中、寄存器相对寻址方式、基址变址寻址方式、相对基址变址寻址方式。
2、逻辑地址和内存分段概念:逻辑地址:逻辑地址是指在计算机体系结构中是指应用程序角度看到的内存单元(memory cell)、存储单元(storage element)、网络主机(network host)的地址。 逻辑地址往往不同于物理地址(physical address),通过地址翻译器(address translator)或映射函数可以把逻辑地址转化为物理地址。
内存分段:内存分段(英语:Memory segmentation),一种电脑内存的管理技术,它将电脑的主内存分成许多区段(segment或sections)。当处理器要进行内存寻址时,会使用一个数值,这个数值包括了某个区段,以及偏移量(offset)。一个程式的目的档(Object file)中也会使用区段,让它们可以链结成执行档,并加载内存中执行。
3、伪指令:ORG 汇编起始命令、END 汇编结束命令、EQU 赋值命令、DATA 数据地址赋值命令、DB 定义字节命令、DW 定义字命令、DS 定义存储空间命令、BIT 位地址符号命令。
数据段和代码段的定义方法:段定义语句用来定义一个逻辑段,每个段以SEGMENT开始,以ENDS结束,整个段的内容都在这两条伪指令之间。
4、8086cpu基本结构:CPU内部结构看, CPU由四部分构成:算术逻辑单元(ALU), 工作寄存器, 控制器和I/O控制逻辑。堆栈:堆栈是一种数据结构,而且是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常用来保护断点和现场。段超越:段超越前缀用来改变默认段寻址,通常内址寻址是数据段或者堆栈段,但你可以在指令前面加上段超越前缀,就可以访问到其它段内的数据。堆栈操作的基本方法:入栈和出栈
5、反汇编:反汇编就是把可执行的二进制文件转为汇编代码,进而可以研究该程序。作用:把软件的代码从EXE中解析出来.通常编写程序是利用高级语言如C,Pascal等语言进行编程的,后再经过编译程序生成可以被计算机系统直接执行的执行文件。反汇编即是指将这些执行文件反编译还原成汇编语言或其他高级语言。
编程设计实验:
一、
(1)、源代码如下:
CODE SEGMENT
ASSUME CS:CODE
START: MOV AX,5678H
MOV BX,8765H
ADD AX,BX
MOV CX,AX
PUSH CX
POP DX
L1:JMP L1
CODE ENDS
END START
最开始IP为0,其余寄存器都为初始值
第一步,将5678H存到了AX寄存器中,IP地址变为0003H。(立即数寻址)
第二部,将8765H存到寄存器BX中,IP地址变为0006H。(立即数寻址)
第三步,将AX与BX相加并存入到AX寄存器中,IP地址变为0008H,FLAGS变为7286H。
第四步,再将AX寄存器中的数据存入CX寄存器中。IP地址变为000A H.
第五步,将CX寄存器中的数据进行压栈,压栈后,SP变为FFFC H,IP变为000B H。
第六步,将数据弹栈,弹入DX寄存器中,弹栈结束后,DX变为DDDD H,SP变为FFFE H, IP变为000C H。
(2)、
在第七行设置了断点,连续执行达到第七行后,堆栈窗口数据为FF FF。
再单步执行PUSH CX 指令后,堆栈窗口数据变为DD DD FF FF。
SS、CX、DX未发生变化,SP从FFFE H 变为 FFFC H。
由于只是将CX中的数据进行压栈,所以SS、CX、DX都未改变,只将CX的值压入堆栈中,所以堆栈窗口数据多了DD DD,且SP要减2,即SP=SP-2,
因此SP变为FFFC H。
在单步执行POP DX指令后,堆栈窗口数据再次变为FF FF。
SS和CX未发生变化,DX变为DDDD H,SP变为FFFE H。
此步为弹栈操作,将堆栈的DD DD弹入DX寄存器中,因此堆栈窗口数据再次变为FF FF,DX寄存器变为DDDD H,且SP要加2,即SP=SP+2。
所以SP=FFFE H。
(3)、
将5678H和8765H改为5678和8765后,单步执行第三行和第四行,AX寄存器变为162E H,BX寄存器变为223D H。
可以看出,将H去掉后,计算机默认5678和8765为十进制数,自动转换为十六进制数并分别存入AX以及BX寄存器中。
二、内存中现有X和Y两个存储单元,分别存有42和-43,利用汇编语言编程计算这两个数之和,并将结果存入SUM单元
源代码如下:
DATA SEGMENT
X DB 42
Y DB -43
SUM DB 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV AL,X
MOV BL,Y
ADD AL,BL
MOV SUM,AL
MOV AH,4CH
INT 21H
CODE ENDS
END START
在第12行设置断点进行调试
发现将42和-43两个十进制数分别存入AX和BX寄存器中,自动变为十进制数
将两数之和存入SUM单元后,-1自动转换为其补码FF
位置为0FE6:0000,42和-43和sum分别以十六进制形式存入数据段中,数据段大小为3字节
在反汇编窗口,代码段位置为从0000FE70到0000FE83,大小为83H-70H+1H=14H=20
流程图:
三、数据段中的一个存储单元X中存放的数据为10H,编程实现将该存储单元中的数据循环左移四位后存放到数据段的另一个存储单元Y中。
代码如下:
DATA SEGMENT
X DW 10H
Y DW 00H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV AX,X
MOV CL,04H
ROL AX,CL
MOV Y,AX
MOV AH,4CH
INT 21H
CODE ENDS
END START
流程图:
四、编程实现三个四位十六进制数1234H,5678H,AAAAH的相加运算,结果存放在数据段的存储单元SUM中。
代码如下:
DATA SEGMENT
X DW 1234H
Y DW 5678H
Z DW 0AAAAH
SUM DD 0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV DX,0
LEA BX,SUM
MOV AX,X
ADD AX,Y
ADC DX,0
ADD AX,Z
ADC DX,0
MOV [BX][0],AX
MOV [BX][2],DX
MOV AH,4CH
INT 21H
CODE ENDS
END START
流程图:
五、使用单字节指令,编程计算两个带符号数的加法,结果存放在数据段200H存储单元中,数据段201H存储单元存放运算结果的符号位,数据段202H单元存放运算结果的进位位(0表示无进位、1表示有进位)
运行结果及代码:
DATA SEGMENT
A1 DB -125
A2 DB 10
ORG 200H
SUM DB 0,0,0
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
CLC
MOV AL,A1
ADC AL,A2
MOV SUM,AL
JS AB
MOV SUM[1],0
JMP DUANDIAN
AB: MOV SUM[1],1
DUANDIAN:JC ABC
MOV SUM[2],0
JMP LOOP
ABC: MOV SUM[2],1
LOOP: JMP LOOP
CODE ENDS
END START
实验总结:
尽管本次实验原理较为简单,但在编写代码以及观察数据的时候还是会遇到大大小小的问题,同时也发现了许多自身的不足以及知识盲点,经过与同学的讨论以及网上的查询,最终还是将问题逐一解决,收获颇丰!
本次实验我知道了8086的寻址方式、逻辑地址以及学会了基本的汇编语言的程序设计,理清了简单的程序流程,掌握了8086系统中机器数的表示方式和TPC-USB集成开发环境程序设计和调试的方法,是自己在接下来的汇编语言学习中更加方便!