汇编语言第2版王爽著课后实验报告详解.docx

上传人:b****4 文档编号:4201799 上传时间:2022-11-28 格式:DOCX 页数:28 大小:1.06MB
下载 相关 举报
汇编语言第2版王爽著课后实验报告详解.docx_第1页
第1页 / 共28页
汇编语言第2版王爽著课后实验报告详解.docx_第2页
第2页 / 共28页
汇编语言第2版王爽著课后实验报告详解.docx_第3页
第3页 / 共28页
汇编语言第2版王爽著课后实验报告详解.docx_第4页
第4页 / 共28页
汇编语言第2版王爽著课后实验报告详解.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

汇编语言第2版王爽著课后实验报告详解.docx

《汇编语言第2版王爽著课后实验报告详解.docx》由会员分享,可在线阅读,更多相关《汇编语言第2版王爽著课后实验报告详解.docx(28页珍藏版)》请在冰豆网上搜索。

汇编语言第2版王爽著课后实验报告详解.docx

汇编语言第2版王爽著课后实验报告详解

 

汇编语言实验报告

班级学号

学生姓名

提交日期

成绩

 

 

实验1-1如下:

用E命令将指令写入内存:

用A命令将指令写入内存:

实验1-2代码如下:

用a命令在2000:

0000处写如要写如的代码,然后用R命令来修改CS为2000,IP修改为0,然后用T命令执行,直到AX中的值为10,因为是默认为十六进制,所以ax中的0010实际代表十进制的16。

如图:

实验1-3:

用D命令输入内存fff0h~fffffh,则可看到:

生产日期为06/15/09在地址为FFFF5~FFFF12处,现在用E命令随便修改一下有:

在window7下虚拟的dos中可以改,但如果重新打开dos中的debug则日期任然不会改变,因为那是ROM。

实验1-4代码如下:

内存地址为B800:

0开始的为显存,是RAM,可以改变其值来在屏幕中显示,其中这一个字符占两个字节,前一个(低)为字符的ASCII码,后一个(高)为要显示的颜色,内存B800:

0和B800:

1这两个字节对应着屏幕中的第一个字符的位置,依次类推,每个屏幕的行有80个字符,对应的内存占160个字节

实验2-1:

(按实验结果填空)

Movax,ffff

Movds,ax

Movax,2200

Movss,ax

Movsp,0100

Movax,[0];ax=5BEA

Addax,[2];ax=5CCA

Movbx,[4];bx=30F0

Addbx,[6];bx=6026

Pushax;sp=00FE;修改的内存单元的地址是2200:

00FE内容是5CCA

Pushbx;sp=00FC;修改的内存单元的地址是2200:

00FC内容是6026

Popax;sp=00FE;ax=6026.

Popbx;sp=0100;bx=.5CCA

Push[4];sp=00FE;修改的内存单元的地址是2200:

00FE内容是30F0

Push[6];sp=00FC;修改的内存单元的地址是2200:

00FC内容是2F36

实验截图如下:

实验2-2(分析问答实验)

答:

因为T命令是单步中断,我们在后面学习后知道,CPU执行中断时会保留现场,即将标志寄存器,CS,IP等入栈,而实验中栈的地址正好是要查询的内存地址,所以即便未对内存单元进行写入命令,但里面的值会因为CPU要保留现场自动被改了

实验3

(1)代码:

ASSUMECS:

CODES

CODESSEGMENT

START:

movax,2000h

movss,ax

movsp,0

addsp,10

popax

popbx

pushax

pushbx

popax

popbx

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

(2)debug跟踪:

(3)用debug跟踪查看PSP中的内容:

可见PSP的头两个字节是CD20,与书上的一致

实验4-1代码如下:

ASSUMECS:

CODES

CODESSEGMENT

START:

movax,0

movds,ax

movbx,200h

movcx,64

s:

mov[bx],al

incal

incbx

loops

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验4-1运行图如下:

实验4-2代码如下:

ASSUMECS:

CODES

CODESSEGMENT

START:

movax,200h

movds,ax

movbx,0

movcx,64

s:

mov[bx],bx

incbx

loops

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

运行结果同实验4-1的一样

实验4-3(补全代码)

ASSUMECS:

CODES

CODESSEGMENT

START:

movax,cs

movds,ax

movax,20h

moves,ax

movbx,0

movcx,16h

s:

moval,[bx]

moves:

[bx],al

incbx

loops

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

因为要将代码复制到0:

200处,则必须知道代码的地址,和代码的长度,代码的地址在cs和IP中,代码的长度可以编译后用U命令查看后确定,这个之前随便打一个数就可以,不影响代码的长度,因为那个数占的空间和真实的长度一样,所以用U命令后在改过来即可

实验4-3的运行图如下:

实验5-1代码如下:

DATASSEGMENT

dw0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h

DATASENDS

STACKSSEGMENT

dw0,0,0,0,0,0,0,0

STACKSENDS

CODESSEGMENT

ASSUMECS:

CODES,DS:

DATAS,SS:

STACKS

START:

MOVAX,stacks

MOVss,AX

movsp,16

movax,datas

movds,ax

pushds:

[0]

pushds:

[2]

popds:

[2]

popds:

[0]

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验5-1运行图如下:

①CPU执行程序后,程序返回前,data段中的数据为多少?

答:

不变如上图

②CPU执行程序后,程序返回前,CS=144Ch,SS=144Bh,DS=144Ah。

③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1.

实验5-2代码如下:

ASSUMECS:

CODES,DS:

DATAS,SS:

STACKS

DATASSEGMENT

dw0123h,0456h

DATASENDS

STACKSSEGMENT

dw0,0

STACKSENDS

CODESSEGMENT

START:

MOVAX,stacks

MOVsS,AX

movsp,16

movax,datas

movds,ax

pushds:

[0]

pushds:

[2]

popds:

[2]

popds:

[0]

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验5-2运行图如下:

①CPU执行程序后,程序返回前,data段中的数据为多少?

答:

不变如上图

②CPU执行程序后,程序返回前,CS=144Ch,SS=144Bh,DS=144Ah。

③设程序加载后,code段的段地址为X,则data段的段地址为X-2,stack段的段地址为X-1.

④对于如下定义的段:

Namesegment

……

Nameends

如果段中的数据占N个字节,则程序加载后,该段实际占用空间为16N倍。

实验5-3代码如下:

CODESSEGMENT

ASSUMECS:

CODES,DS:

DATAS,SS:

STACKS

START:

MOVAX,stacks

MOVsS,AX

movsp,16

movax,datas

movds,ax

pushds:

[0]

pushds:

[2]

popds:

[2]

popds:

[0]

MOVAH,4CH

INT21H

CODESENDS

DATASSEGMENT

dw0123h,0456h

DATASENDS

STACKSSEGMENT

dw0,0

STACKSENDS

ENDSTART

实验5-3运行图如下:

①CPU执行程序后,程序返回前,data段中的数据为多少?

答:

不变如上图

②CPU执行程序后,程序返回前,CS=144Ch,SS=144Eh,DS=144Dh。

③设程序加载后,code段的段地址为X,则data段的段地址为X+3,stack段的段地址为X+4。

实验5-4:

如果将

(1),

(2),(3)题中的最后一条伪指令“endstart”改为“end”(也就是说,不指明程序的入口),则哪个程序任然可以正确执行?

答:

程序都可以正确执行,因为去掉start后,由于没有的标志,系统会将从code段的起始位置当作程序代码的开始处,然后一直执行下去,而这三个程序在start前没有其他的内容,去掉start也就不影响期功能了

实验5-5代码如下:

ASSUMECS:

CODES

CODESSEGMENT

aSEGMENT

db1,2,3,4,5,6,7,8

aENDS

bSEGMENT

db1,2,3,4,5,6,7,8

bENDS

CCSEGMENT

db0,0,0,0,0,0,0,0

CCENDS

START:

MOVAX,a

MOVDS,AX

movsi,0

Movcx,8

s:

movax,0

addal,[0+si]

addal,[16+si]

Mov[32+si],al

incsi

loops

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验5-5运行图如下:

实验5-6代码如下:

aSEGMENT

dw1,2,3,4,5,6,7,8,9,0ah,0bh,0ch,0dh,0eh,0fh,0ffh

aends

bSEGMENT

dw0,0,0,0,0,0,0,0

bENDS

CODESSEGMENT

ASSUMECS:

CODES

START:

MOVAX,a

MOVDS,AX

movbx,0

movax,b

movss,ax

movsp,16

movcx,8

s:

push[bx]

addbx,2

loops

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验5-6运行图如下:

实验6代码如下:

stacksgSEGMENT

dw0,0,0,0,0,0,0,0

stacksgENDS

datasgSEGMENT

db'1.display'

db'1.brows'

db'1.replace'

db'1.modifly'

datasgENDS

CODESSEGMENT

ASSUMECS:

CODES,DS:

DATASg,SS:

STACKSg

START:

MOVAX,DATASg

MOVDS,AX

movbx,0

movax,stacksg

movss,ax

movsp,16

movcx,4

s0:

pushcx

movsi,3

movcx,4

s:

moval,[bx+si]

andal,11011111b

mov[bx+si],al

incsi

loops

addbx,16

popcx

loops0

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验6运行图如下:

实验7代码如下:

DATASSEGMENT

Db'1975','1976','1977','1978','1979','1980','1981','1982','1983','1984','1985','1986','1987','1988','1989','1990','1991','1992','1993','1994','1995'

dd16,22,382,1356,2390,8000,16000,24486,50065,97497,140417,197514

dd345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000

dw3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226

dw11542,11430,15257,17800

DATASENDS

tableSEGMENT

db21dup('yearsummne?

?

')

tableENDS

CODESSEGMENT

ASSUMECS:

CODES

START:

MOVAX,DATAS

MOVDS,AX

movbp,0

movax,table

moves,ax

movdi,0

movbx,0

movcx,21;循环21次,因为有21行

s:

movsi,0;将年份入表

movax,ds:

[si+bp];si是首地址,bp是相对si的偏移地址,bp每次加4

moves:

[di],ax

movax,ds:

[si+bp+2]

moves:

[di+2],ax

movsi,84;将总收入入表

movax,ds:

[si+bp]

moves:

[di+5],ax

movax,ds:

[si+bp+2]

moves:

[di+7],ax

movsi,168;将人数入表

movax,ds:

[si+bx];bx和bp的功能一样,只不过因为它只能每次加2

moves:

[di+10],ax

movax,es:

[di+5];求人均收入并入表

movdx,es:

[di+7]

divwordptres:

[di+10]

moves:

[di+13],ax

adddi,16

addbp,4

addbx,2

loops

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验7运行图如下:

实验8代码如下:

CODESSEGMENT

ASSUMECS:

CODES

movax,4c00h

int21h

START:

MOVAX,0

s:

nop

nop

movdi,offsets

movsi,offsets2

movax,cs:

[si]

movcs:

[di],ax

so:

jmpshorts

s1:

movax,0

int21h

movax,0

s2:

jmpshorts1

nop

CODESENDS

ENDSTART

程序能正常执行完毕,因为在start后的第7,8行将s2处的代码写入了s处的两个空字节单元,而内容为EBF0,意思是从将当前IP的值赋成(IP)-F0(八位位移,补码形式),赋值后IP指向了movax,4c00h,接着就结束程序了

实验9代码如下:

DATASSEGMENT

db'welcometomasm!

'

DATASENDS

CODESSEGMENT

ASSUMECS:

CODES,DS:

DATAS

START:

MOVAX,DATAS

MOVDS,AX

movbx,0

movax,0b800h

moves,ax

movsi,1980;将显示的区域定在屏幕中间

movcx,16

s:

moval,[bx]

moves:

[si],al

movah,01110010b;将颜色定为绿色

moves:

[si+1],ah

addsi,2

incbx

loops

movbx,0

movsi,2140;下一行接着从来

movcx,16

s1:

moval,[bx]

moves:

[si],al

movah,00100100b;颜色为绿底红色

moves:

[si+1],ah

addsi,2

incbx

loops1

movbx,0

movsi,2300;同上

movcx,16

s2:

moval,[bx]

moves:

[si],al

movah,01110001b

moves:

[si+1],ah

addsi,2

incbx

loops2

MOVAH,4CH

INT21H

CODESENDS

ENDSTART

实验9运行图如下:

实验10-1代码如下:

DATaSEGMENT

db'welcometomasm!

',0

DATAENDS

CODESSEGMENT

ASSUMECS:

CODES

START:

movdh,8

movdl,3

movcl,2

MOVAX,DATA

MOVDS,AX

movsi,0

callshow_str

MOVAH,4CH

INT21H

show_str:

movax,data

movds,ax

movsi,0

movax,0b800h

moves,ax

moval,160;将乘数(行数)默认放在al中

muldh;想乘之后结果放在ax(行的偏移地址)中

movdh,0

adddl,dl;因为一个字符用两个字节,所以二倍,及列数的偏移地址

addax,dx将列的加到行上就是偏移地址了

movbx,ax;bx为偏移地址

s:

movcl,2

movch,0

moval,[si]

movah,0;开始复制字符到显存中

moves:

[bx],al

moves:

[bx+1],cl;设置颜色

movcx,ax

inccx;判断cx是否为0

jcxzok

incsi

addbx,2

loops

ok:

ret

CODESENDS

ENDSTART

实验10-1运行图如下:

实验10-2代码如下:

CODESSEGMENT

ASSUMECS:

CODES

START:

movax,4240h

movdx,00fh

movcx,0ah

calldivdw

MOVAH,4CH

INT21H

divdw:

movdi,ax;将ax中的4240先保存起来

movax,dx;将dx中ooof赋给在ax

movdx,0

divcx

movsi,dx;将余数先存到si中,因为后面马上会占用dx

movdx,ax;将取商的值赋给dx,这里的dx为高位

pushdx

movdx,si;将余数放入dx中

movax,di

divcx

movcx,dx

popdx

ret

CODESENDS

ENDSTART

实验10-2运行图如下:

实验10-3代码如下:

DATa1SEGMENT

dw123,12666,1,8,3,38

DATA1ENDS

data2SEGMENT

db16dup(0)

data2ENDS

data3segment

db16dup(0)

data3ends

CODESSEGMENT

ASSUMECS:

CODES

START:

MOVAX,DATA1

MOVDS,AX

movbx,0

movcx,6

calldtoc;调用dtoc子程序

movdh,8

movdl,3

movcl,2

movch,0

callshow_str;调用show_str子程序

MOVAH,4CH

INT21H

dtoc:

movax,data2;data2中是用来存放字符的,不过是反顺序的“123”在其中变成了“321”

moves,ax

movdi,0

movbp,0

s1:

pushcx;cx入栈,保存起来

movax,[bx]

s2:

movdx,0;因为12666%10的结果会溢出,所以有32位当被乘数,ax中存放商

movcx,10

divcx

adddl,30h;加上30h后就变成ascii对应的字符码了

moves:

[di],dl;存入data2段中

movcx,ax;判断商是否为零,为零则结束循环

jcxzok

incdi

jmps2

ok:

pushds;因为后面用到ds,而前面又有,所以保存

pushdi

subdi,1;因为di指向的后一个元素,这里减一使其回到当前元素

Movdi,dx;当前的值保存到dx中

movax,data3;data2中数据为“3216662118383”,这里将其反置为“1231266618338”

movds,ax

s3:

moval,es:

[di]

movds:

[bp],al

cmpdx,bp;判断反序复制是否结束的,bp到达原来di所指向的元素则结束

jeok1

incbp;反序

decdi

jmps3

ok1:

addbx,2

popdi;按顺序还原

popds

popcx

loops1

ret

show_str:

movax,data3;显示字符的子程序,前面已做过

movds,ax

movsi,0

movax,0b800h

moves,ax

moval,160

muldh

movdh,0

adddl,dl

addax,dx

movbx,ax

s:

movcx,2

moval,[si]

movah,0

moves:

[bx],al

moves:

[bx+1],cl

addbx,2

movcx,ax

inccx

incsi

loops

ok2:

ret

CODESENDS

ENDSTART

实验10-3运行图如下:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1