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 .asm”命令,产

生“.exe”可执行文件。注意,进程中“.obj”文件也会产生,若是汇编程序中有

过量犯错指令,“.exe”文件就可不能产生。

c) 利用“debut .exe”执行并debug程序。

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*BC (算法示用意如图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

;

;

;

;

;

;

;