学习<<汇编语言 -王爽>>,自已完成的一道课程设计题 (5)

课程设计1 (材料详见书上211页)


题目描述:

以下是我解答的完整的代码:

:>----------------------------------------------------------------------------------------

assume cs:codesg, ss:stacksg

datasg segment

db ‘1975‘, ‘1976‘, ‘1977‘, ‘1978‘, ‘1979‘, ‘1980‘, ‘1981‘, ‘1982‘, ‘1983‘

db ‘1984‘, ‘1985‘, ‘1986‘, ‘1987‘, ‘1988‘, ‘1989‘, ‘1990‘, ‘1991‘, ‘1992‘

db ‘1993‘, ‘1994‘, ‘1995‘

dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514

dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000

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

dw 11542,14430,15257,17800

datasg ends

stacksg segment

dw 16 dup(0)  ;栈-用来暂存数据

stacksg ends

mathsg segment

db 16 dup(0)  ;用来保存十进制数对应的ASCII码值

mathsg ends

stringsg segment

db 80 dup(20h)  ;定义字符串, 长度为一行, 用空格符初始化

stringsg ends

codesg segment

start: mov ax, datasg

mov ds, ax

mov ax, stacksg

mov ss, ax

mov sp, 20h  ;初始化栈

mov ax, stringsg

mov es, ax

mov bx, 0  ;增量为4个字节

mov bp, 0  ;增量为2个字节

mov cx, 21 ;总共要处理的行数

mov dh, 0  ;指定显示的行

mov dl, 0  ;指定显示的列

p0: push cx  ;外层循环

push dx

;----下面处理每行的日期数据

mov cx, 4

mov si, 0

mov di, 0

p1: mov al, ds:[bx][si]

mov es:[di].2, al

inc si

inc di

loop p1

;----下面处理每行的收入数据

mov si, 2

mov ax, ds:[bx].54h

mov dx, ds:[bx][si].54h

call dtoc

push ds

mov ds, di

mov ch, 0

mov di, 0

p2: mov cl, ds:[si]

jcxz p2end

mov es:[di].10h, cl

inc si

inc di

jmp p2

;----下面处理每行的雇员数据

p2end: pop ds

mov ax, ds:[bp].0A8h

mov dx, 0

call dtoc

push ds

mov ds, di

mov ch, 0

mov di, 0

p3: mov cl, ds:[si]

jcxz p3end

mov es:[di].20h, cl

inc si

inc di

jmp p3

;----下面处理每行的平均收入数据

p3end: pop ds

mov si, 2

mov ax, ds:[bx].54h

mov dx, ds:[bx][si].54h

mov cx, ds:[bp].0A8h

call divdw

call dtoc

push ds

mov ds, di

mov ch, 0

mov di, 0

p4: mov cl, ds:[si]

jcxz p4end

mov es:[di].30h, cl

inc si

inc di

jmp p4

;----下面加上结束符,并且显示处理好的行内容

p4end: pop ds

mov di, 4Fh

mov byte ptr es:[di], 0

;----运行到这里时已构造好一行的显示内容,存在stringsg段中

pop dx

mov cl, 07h

mov di, es

mov si, 0

call show_str  ;显示一行内容

inc dh

add bx, 4

add bp, 2

pop cx

dec cx

cmp cx, 0

jne top0

je toend

top0: jmp far ptr p0

toend: mov ax, 4c00H

int 21H

;子程序(用来在屏幕指定位置显示内容的子程序, 内容默认放在ds段中)

;  参数:dh-显示的行数, dl-显示的列数, cl-属性字节, di-内容所在的段, si-移量地址

;  返回:无

show_str: push ds

push es

push ax

push bx

push dx  ;以上保存子程序中要用到的寄存器

mov ds, di

mov ax, 0B800h  ;显存首地址

mov es, ax

mov al, 160  ;显存中每行所占的字节数(每行能显示80个字符)

mul dh

mov bx, ax

mov al, 2  ;显存中每个显示字符所占的字节数(显示字符=属性字节+ASCII码)

mul dl

add bx, ax  ;此时bx为由参数指定显示位在显存中的首地址

mov ch, 0

mov dl, cl  ;因为要用cx来检测是否处理到字符串的结尾0, 先用dl保存参数cl

s0: mov cl, ds:[si]  ;取出之前处理好的一个字符

jcxz sok

mov byte ptr es:[bx], cl  ;往显存中存入ASCII码

mov byte ptr es:[bx].1h, dl  ;往显存中存入属性字节

inc si  ;移动到下一个字符

add bx, 2  ;移动到下一个显存字符空间的首地址

jmp s0

sok: pop dx

pop bx

pop ax

pop es

pop ds

ret

;子程序(用来转成十进制数对应的ASCII码的子程序)

;  参数:ax-保存数值的低16位, dx-保存数值的高16位

;  返回:si-保存十进制ASCII码的首地址, di-保存段地址

dtoc: push ds

push bx

push cx

mov cx, mathsg

mov ds, cx

mov di, cx

mov si, 0Eh  ;初始化si指向mathsg段中倒数第二个字节空间

d0: mov cx, 0Ah  ;cx保存除数

call divdw

add cl, 30h  ;由于除数是10 所以结果中的余数一定小于10,取cl就行了

mov byte ptr [si], cl  ;保存对应的十进制数的ASCII值

call zerodw

jcxz dok

dec si

jmp d0

dok: pop cx

pop bx

pop ds

ret

;子程序(进行不产生溢出的除法运算)

;  参数:dx为被除数的高位字,ax为被除数的低位字,cx为除数占一个字空间

;  返回:dx保存商的高位字,ax保存商的低位字,cx保存余数点一个字空间

divdw: push bx ;下面要用bx来保存第一次除法结果中的商,先入栈保存下之前的信息,以免冲突

push ax ; ax现在存有参数,但要用到ax参与除法运算,所以也先入栈保存份

mov ax, dx

mov dx, 0

div cx  ; 执行分解后的第一次除法: H/n

mov bx, ax  ; bx保存第一次除法结果中的商

pop ax  ; 将入栈保存的ax参数值出栈,此时dx的值为第一次除法结果中的余数

div cx  ; 执行第二次除法: [rem(H/n)*65536+L]/n

mov cx, dx  ; 根据题目要求,将除法结果中的余数用cx保存

mov dx, bx  ; 根据题目要求,将除法结果中的高位字用dx保存

pop bx  ; 还原bx的值,避免子程序之外也用到了bx而产生寄存器冲突

ret

;子程序(判断32位的数是否为0)

;  参数:dx为被除数的高位字,ax为被除数的低位字

;  返回:cx 当dx、ax都为0时才为0

zerodw: cmp dx, 0

jne nz

cmp ax, 0

jne nz

mov cx, 0

jmp zok

nz: mov cx, 1

zok: ret

codesg ends

end start

:<----------------------------------------------------------------------------------------

运行结果:

总结:

调试了一个晚上,终于弄出来了,很激动,又进一小步。调试时又出现了死循环,由于对栈的操作不当引起的,下次一定要注意入栈与出栈要配对,并且出栈顺序与入栈顺序相反。

-------------   以上的习题部分及代码引用于王爽老师的<<汇编语言>>第二版  ----------------

时间: 2024-10-05 09:13:23

学习<<汇编语言 -王爽>>,自已完成的一道课程设计题 (5)的相关文章

汇编语言 王爽

汇编语言 王爽 目录 汇编语言... 1 王爽... 1 第一章:基础知识 第二章:寄存器 第三章 寄存器(内存访问) 第四章 第一个程序 第六章  包含多个段的程序 第七章 更灵活定位内存的方法 第八章 数据处理的两个基本问题 第一章:基础知识 汇编语言:汇编语言是什么?为什么学习汇编语言?学习汇编语言是学习什么? 早起使用机器语言,但机器语言 晦涩难懂也难以使用,所以出现了汇编语言.即用通熟易懂的汇编指令替代全是二进制0和1的机器指令. 于是也就出现了编译器,即把汇编指令翻译成机器指令. 机

汇编语言 王爽第二版 总结

汇编语言 王爽第二版 总结,所以内容都是8086的 summary asssembly ,汇编总结 why: 最初始的编程语言就是使用打孔机,打出来的0 1 代码,然后把卡片插入到电脑中运行然后 看输出结果,这种纯01的二进制代码,编写困难调试困难运行结果的显示看着也很蛋疼,就像 一个简单的"hello world",11个字符,需要11×8个二进制,并且再进行输出,就更麻烦,因为 全部都是二进制,代码.为了更高效的开发程序,就出现了汇编语言,用来代替二进制代码的输入. what: 汇

汇编语言(王爽)pdf

下载地址:网盘下载 <汇编语言(第2版)>是各种CPU提供的机器指令的助记符的集合,人们可以用汇编语言直接控制硬件系统进行工作.汇编语言是很多相关课程(如数据结构.操作系统.微机原理等)的重要基础.为了更好地引导.帮助读者学习汇编语言,作者以循序渐进的思想精心创作了<汇编语言(第2版)>.<汇编语言(第2版)>具有如下特点:采用了全新的结构对课程的内容进行组织,对知识进行最小化分割,为读者构造了循序渐进的学习线索:在深入本质的层面上对汇编语言进行讲解:对关键环节进行深入

汇编语言 王爽著

汇编语言让我们深入了解计算机底层,值得去学习了解. 汇编语言(assembly language)是一种用于电子计算机.微处理器.微控制器或其他可编程器件的低级语言,亦称为符号语言.在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数的地址.在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令.普遍地说,特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植.

汇编语言(王爽) 第1章基础知识

1.1 机器语言 机器语言就是机器指令的集合.机器指令是啥呢?就是一列二进制的数据,计算机把它转成高低电平,使计算机的其他器件驱动并运算.(计算机如何使用2进制语言?) 早期程序都是用机器语言写的,但是有个问题就是太麻烦,数据信息太长,写错一个0或1就会来BUG了. 这种机器语言根本不是人写的,注定会被淘汰. 1.2 汇编语言 这个时候,汇编语言就挺身而出. 汇编语言就是机器语言的便于记忆的格式把 一个指令1000100010001000 表示把寄存器A1的内容弄到寄存器A2上.如下 操作介绍:

汇编语言 王爽著第三章

汇编语言(assembly language)是一种用于电子计算机.微处理器.微控制器或其他可编程器件的低级语言,亦称为符号语言.在汇编语言中,用助记符(Mnemonics)代替机器指令的操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数的地址.在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令.普遍地说,特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植.

汇编语言(王爽) 第6章包含多个段的程序

程序到了内存中我们分为code(代码)段,也就是大部分指令段,数据段,栈 6.1 在代码段中使用数据 上图 dw表示define word定义一个字,16位 会出现cs执行的前16位是数据段,后面才是指令,所以要把IP设成10h 或者直接在第一条指令前面在start,再在最后面的end start 程序运行的第一条不是汇编指令可能会报错把 6.2 在代码段中使用栈 这的题目都是从内存单元的数据换到另一个内存单元 开始奇怪,为啥不直接换,还要专门定义一个栈空间出来做个中间体 查了资料才知道,内存单

汇编语言(王爽) 第11章 标志寄存器

这里讲一个特殊的寄存器,flag 先看flag的16位显示 11.1 zf 指令执行后,结果0,ZF=1 指令执行后,结果不为0,ZF=0 11.2 pf 指令执行后,所有bit位中1的个数是否位偶数,若为偶数,那么pf=1 若为奇数,pf=0 11.3 sf 指令执行后,结果负,SF=1 指令执行后,结果不为负,SF=0 11.4 cf 进位 若出现进位,那么CF=1 没有的话CF=0 11.5 of 溢出, 数字的溢出. 8位范围是-128-127 若130就是溢出了 11.6 abc指令

汇编语言(王爽) 第7章 寻址方法

这章讲一些寻址方法,对前面寻址方法的总结把 7.1 and or 2个指令 上栗子 mov al,00001111b and al,11110000b al=00000000b mov al,00001111b or al,11110000b al=11111111b 7.2 ASCII码 之前就写过一篇ACSII码的,这里主要写下我们在键盘上按键再输出到屏幕的过程 我们在键盘上按下a键 这个信息被传到计算机,计算机用ASCII码对它编码,成为61h, 再扔到一个内存段中 文本编辑器把内存中的6