2024年6月1日发(作者:)
汇编语言程序设计
实验二 MASM 汇编器利用
学号: 姓名:
1. 利用MASM为DOS和Windows编程:
a) DOS中运行的程序:先输入程序,
.386
.model flat, stdcall
option casemap :none
include masm32include
include masm32include
include masm32include
includelib masm32lib
includelib masm32lib
.data
HelloWorld db "Hello World!", 0
.code
start:
invoke StdOut, addr HelloWorld
invoke ExitProcess, 0
end start
再打开DOS命令提示符界面,输入“masm32binml /c /Zd /coff ”
在没错误情形下,能够连接文件,输入“
masm32binLink /SUBSYSTEM:CONSOLE
在工作目录中会产生可运行文件,运行并记录运行结果。
b)
Windows 中运行的程序:先修改程序,
.386
.model flat, stdcall
option casemap :none
include masm32include
include masm32include
include masm32include
includelib masm32lib
includelib masm32lib
.data
HelloWorld db "Hello World!", 0
,
“
.code
start:
invoke MessageBox, NULL, addr HelloWorld, addr HelloWorld, MB_OK
invoke ExitProcess, 0
end start
用命令“
masm32binml /c /Zd /coff
”编译程序,再用命令
“
masm32binLink /SUBSYSTEM:WINDOWS
”连接程序,运行并记录运行结果。
2. 利用Debug调试编辑执行汇编代码的步骤:
a) 利用文本编辑器(如:Notepad),编辑汇编程序,并将程序在工作子目录中,保留
为以“.asm”为后缀的文件中。
b) 打开 DOS 命令提示符界面,在工作子目录下输入“ml
生“.exe”可执行文件。注意,进程中“.obj”文件也会产生,若是汇编程序中有
过量犯错指令,“.exe”文件就可不能产生。
c) 利用“debut
3. 程序模板:
DATA_HERE
DATA_A
SEGMENT
DW 1 DUP(0)
DW 1 DUP(0)
; 在数据段中预留位置
; 预留另一个位置
DATA_B
; 预留位置的初始值都是 0H
DATA_HERE
STACK_HERE
DW
SEGMENT STACK
100 DUP(0)
LABEL
; 内存中堆栈位置
; 栈顶位置命名
ENDS
TOP_STACK WORD
STACK_HERE ENDS
CODE_HERE SEGMENT
DS:DATA_HERE, SS:STACK_HERE ASSUME CS:CODE_HERE,
START: MOV AX, DATA_HERE
; DS 寄放器初始化 MOV DS, AX
MOV AX, STACK_HERE
MOV SS, AX ; SS 寄放器初始化
;初始化堆栈指针 MOV SP, OFFSET TOP_STACK
;
; 在此顺序输入程序指令
;
INT 3H
CODE_HERE
END START
; 断点
ENDS
4. 解析Intel x86 指令:
a) 将模板程序复制为
b) 将表1中的代码复制到程序中
c) 生成“”并debug那个程序
d) 利用“-u”分解程序
e) 填表说明每条指令
f) 回答下列问题:
i. 将表格 1空白处填满
ii. 一些指令不包括ModR/M字节,指出这些指令
iii. 说明段覆盖前缀字节,说明什么缘故指令MOV DS:[DI+0203H]中,BX不需要
前缀字节,而指令MOV DS:[BP+2H]中,DX需要前缀字节?
表格 1
指令
ADD AX, BX
ADC BX, ES:[SI]
TEST AX, 0305H
MOV DS:[BP+2h], DX
MOV DS:[DI+0203H], BX
AND AL, CH
OR AH, 03H
ROL AX, CL
JMP FINISH
(JMP 跳向程序最后一条
指令)
段覆盖前缀操作码
Mod
字节(HEX) (OP)
Reg
r/m
位移量 字节数
5.利用汇编语言程序解方程
f
x
x
是一件不容易的情形。一样利用运算机来求解,
都是编写汇编语言程序计算并查表求解复杂函数。下面表2是利用汇编语言求解
f
x
表格 2
x
的求解表的部份内容。
f(x) x 2
10
(十进制数)
0
1024
1448
1774
2048
f(x) x 2
10
(十六进制数)
0000H
0400H
05A8H
06EEH
0800H
X(十进制数)
0
1
2
3
4
5
6
2290
2508
08F2H
09CCH
将表3的空白处填满,再将程序缺失的部份补上,使程序能够按表3计算f(x)+f(y)。
表格 3
x(十进制数)
1
2
6
4
; Filename:
y(十进制数)
3
5
5
3
(f(x)+f(y))x2
10
(十进制数)
(f(x)+f(y))x2
10
(十六进制数)
.MODEL SMALL
.STACK 64
.DATA
ORG 0006H
DATA_T DW 0,1024,1448,1774,2048,2290,2508 ; 查表
ORG 0026H
DATA_X DW 1,2,6,4
ORG 0046H
DATA_Y DW 3,5,5,3
ORG 0066H
DATA_R DW 4 DUP(0)
ORG 0086H
DATA_C DW 4 ; number of results
.CODE
MAIN PROC FAR
MOV AX, @DATA
MOV DS, AX
MOV CX, DATA_C
; 设置计数器
; SI: 指向第一个x值的指针
; DI: 指向第一个y值的指针e
; BP: 指向第一个结果值的指针
; 载入数据段地址
; 结果
; y 的值
; x 的值
MOV SI, OFFSET DATA_X
MOV DI, __
MOV BP, __
;
LOOP1: MOV AX, __
SAL AX, __
MOV BX, __
ADD BX, AX
MOV DX, __
MOV AX, __
SAL AX, __
; x 的值
; x * 2, 表中每项占两字节
; BX: 指向表的指针
; 在表中发觉项
; f(x) --> DX
; y --> AX
; y * 2
; BX: 指向表的指针 MOV BX, OFFSET DATA_T
ADD BX, AX
ADD DX, [BX]
MOV __, DX
ADD SI, 2H
ADD DI, __
ADD BP, __
DEC __
__ LOOP1
INT 3H
MAIN ENDP
END MAIN
; 在表中发觉项
; f(x) + f(y) --> DX
; 存储结果,需要覆盖DS的前缀
; 修改指向x的指针
; 修改指向y的指针
; 修改指向结果的指针
; 计数器减1
; 为完成跳回LOOP1标签位置
; 中断点
其中,现行词ORG用来标示地址偏移量的起始地址。在MASM汇编器中,由ORG概念的
数据段内地址偏移量,实际是字节数加上一个固定的数值。
6.把程序“”中的缺失部份补上,那个程序用来
计算两个32-bit无符号数之间的乘法。
利用两个16-bit无符号数之间乘法指令MUL计算:A*BC (算法示用意如图1所示)。
图 1
对程序进行汇编,并运行程序。将结果填入表4。将可运行程序附在报告后面。MUL指令
句法:
MUL r/mem16
其中:r/mem16操作数是16-bit寄放器或内存位置。结果DX::AX=AX*r/mem16。(DX寄存
结果的高16-bit,AX寄存结果的低16-bit)
表格 4
编号
十六进制数
A
十进制数
十六进制数
B
十进制数
C=A*B
十六进制数
十进制数
1
2
3
3456789A
33
FEDCBA98
9900
FFFFEEEE
4
10 34
; Filename:
.MODEL SMALL
.STACK 100
.DATA
MUL_CAND_L DW 1 DUP(0)
MUL_CAND_H DW 1 DUP(0)
MUL_LIER_L DW 1 DUP(0)
MUL_LIER_H DW 1 DUP(0)
PRODUCT_0 DW 1 DUP(0)
PRODUCT_1 DW 1 DUP(0)
PRODUCT_2 DW 1 DUP(0)
PRODUCT_3 DW 1 DUP(0)
.CODE
MAIN PROC FAR
MOV AX, @DATA
MOV DS, AX
MOV AX, MUL_CAND_L
MUL __
MOV CX, AX
MOV BP, DX
MOV AX, __
MUL MUL_LIER_H
MOV DI, AX
MOV SI, DX
MOV AX, MUL_CAND_H
MUL __
ADD BP, __
___ DI, DX
ADC SI, __
MOV AX, MUL_CAND_L
MUL __
ADD __, AX
ADC DI, __
ADC __, 0H
MOV PRODUCT_0, CX
MOV PRODUCT_1, BP
MOV PRODUCT_2, DI
MOV PRODUCT_3, SI
INT 3H
MAIN ENDP
END MAIN
载入数据段地址
有进位时调整 PROD_3
保留 PROD_0
保留 PROD_1
保留 PROD_2
保留 PROD_3
中断点
; A_L --> AX
; A_L * B_L --> DX, AX
; PROD_0 --> CX
; PROD_1 --> BP
; A_H --> AX
; A_H * B_H --> Dx, AX
; PROD_2 --> DI
; PROD_3 --> SI
; A_H --> AX
; A_H * B_L --> DX, AX
; Update PROD_1
; Update PROD_2
; Adjust PROD_3 if there is a carry-in
; A_L --> AX
; A_L * B_H --> DX, AX
; Update PROD_1
; Update PROD_2
;
;
;
;
;
;
;


发布评论