汇编语言程序设计(第四版)第4章【课后答案】

更新时间:2023-09-03 06:38:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

汇编语言程序设计(第四版)第4章【课后答案】,

汇编语言程序设计 第四版

【课后习题答案】 --囮裑為檤

第4章 基本汇编语言程序设计

〔习题4.1〕例题4.2如果要求算术右移8位,如何修改程序。

〔解答〕

思路: 首先由最高位字节向次低位字节传送……次低位字节向最低位字节传送(共7次);再判最高位字节符号位,如为0,送00h到最高位字节;如为1,送ffh到最高位字节。传送可参考例题4.2,不过应从第一号字节送第零号字节,……最高位字节向次低位字节传送;也可以用循环来完成:

.model small

.stack 256

.data

qvar dq 1234567887654321h

.code

.startup

mov cx,7

mov si,1

again: mov al, byte ptr qvar[si]

mov byte ptr qvar[si-1],al

inc si

loop again

test al,80h

jz ezz

mov bl,0ffh

jmp done

ezz: mov bl,0

done: mov byte ptr qvar[7],bl

.exit 0

end

〔习题4.2〕例题4.2如果要求算术左移7位,如何用移位指令实现。

〔解答〕

思路:可设计外循环体为8个字节左移一次,方法是:最低位字节算术左移一次, 次低位字节至最高位字节依次带 CF 位循环左移一次(内循环共8次),外循环体控制执行7次即可。

.model small

.stack 256

.data

qvar dq 1234567887654321h

汇编语言程序设计(第四版)第4章【课后答案】,

.code

.startup

mov dx, 7 ;外循环次数

mov ax, byte ptr qvar[0] ;最低位字节送ax

lpp: shl ax, 1 ;最低位字节左移一次,其d7移入CF位

mov si, 1

mov cx, 7 ;内循环次数

again: rcl byte ptr qvar[si], 1 ;高位字节依次左移 P50

inc si

loop again

dec dx

jnz lpp

.exit 0

.end

〔习题4.3〕将AX寄存器中的16位数连续4位分成一组,共4组,然后把这4组数分别放在AL、BL、CL和DL寄存器中。

〔解答〕

思路:设这四组从低位到高位分别放在AL、BL、CL和DL寄存器中。仅列出代码段: mov bl, al ;将al中的两组分开

and al, 0fh ;屏蔽高四位后送al

mov cl, 4 ;原al中的数据逻辑右移4次送bl shr bl, cl mov dl, ah ;将ah中的两组分开 and dl, 0f0h ;屏蔽低高四位后送dl

mov cl, 4 ;原ah中的数据逻辑右移4次送dl

shr dl, cl

mov cl, ah ;屏蔽高四位后送cl

and cl, 0fh

〔习题4.4〕编写一个程序,把从键盘输入的一个小写字母用大写字母显示出来。 〔解答〕

getkey: mov ah, 1 ;从键盘输入,出口:al存键值

int 21h

cmp al, 'a' ;判键值是小写字母?

jb getkay

cmp al, 'z'

ja getkay

sub al,20h ;是小写字母转换为大写字母

mov dl,al

mov ah, 02h ;显示

int 21h

〔习题4.5〕已知用于LED数码管显示的代码表为:

汇编语言程序设计(第四版)第4章【课后答案】,

LEDtable DB 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h

DB 80h,90h,88h,83h,0c6h,0c1h,86h,8eh

它依次表示0 ~ 9、A ~ F这16个数码的显示代码。现编写一个程序实现将lednum中的一个数字(0 ~ 9、A ~ F)转换成对应的LED显示代码。

〔解答〕

.model small

.stack 256

.data

LEDtable DB 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h

DB 80h,90h,88h,83h,0c6h,0clh、86h,8eh

lednum DB ?

.code

.startup

mov bx, offset LEDtable

mov al, lednum

xlat ;al中存有对应的LED显示代码

.exit 0

end

〔习题4.6〕编制一个程序,把变量bufX和bufY中较大者存入bufZ;若两者相等,则把其中之一存入bufZ中。假设变量存放的是8位无符号数。

〔解答〕

.model small

.stack 256

.data

bufx db ?

bufY db ?

bufz db ?

.code

.startup

mov al, bufX

mov bl, bufY

cmp al,bl

ja next

mov bufZ, bl

jmp done

next: mov bufZ, al

done: .exit 0

end

〔习题4.7〕设变量bufX为有符号16位数,请将它的符号状态保存在signX,即:如果X大于等于0,保存0;如果X小于0,保存-1(ffh)。编写该程序。

〔解答〕

.model small

汇编语言程序设计(第四版)第4章【课后答案】,

.data

bufX dw -7

signX db ?

.code

.startup

cmp bufX,0 ;test bufX,80h

jl next ;jnz next

mov signX,0

jmp done

next: mov signX,-1

done: .exit 0

end

〔习题4.8〕bufX、bufY和bufZ是3个有符号16进制数,编写一个比较相等关系的程序:

(1)如果这3个数都不相等,则显示0;

(2)如果这3个数中有两个数相等,则显示1;

(3)如果这3个数都相等,则显示2。

〔解答〕

.model small

.stack 256

.data

bufx dw ?

bufY dw ?

bufz dw ?

.code

.startup

mov ax, bufX

mov bx, bufY

mov cx, bufZ

mov dl, '0'

cmp ax,bx

jnz next1

inc dl

next1: cmp ax,cx

jnz next2

inc dl

next2: cmp bx,cx

jnz next3

inc dl

next3: cmp dl, 3

jb next4

mov dl, 2

next4: mov ah,02h ;显示

汇编语言程序设计(第四版)第4章【课后答案】,

.exit 0

end

〔习题4.9〕例题4.8内外循环次数共是多少?如果要求按从大到小排序,程序如何修改? 〔解答〕

外循环次数是: count-1次 (19次)

内循环次数是: (count-1)!次 ( 19! 次)

内外循环次数共是 count-1 + (count-1)!次 ,即 19+19!次

〔习题4.10〕串操作指令常要利用循环结构,现在不用串操作指令实现字符串string1内容传送到字符串string2,字符长度为count。

〔解答〕

.model small

.stack 256

.data

string1 db 'good morning!'

len = $-string1

string2 db len dup(?)

.code

.startup

mov cx, len ;字符数

mov si, offset string1 ;源指针

mov di, offset string2 ;目标指针

again: mov al, [si] ;送一个字符

mov [di], al

inc si ;修改指针

inc di ;修改指针

loop again ;cx=cx-1,cx=0时退出循环

.exit 0

end

〔习题4.11〕不用串操作指令求主存0040h : 0开始的一个64KB物理段中共有多少个空格? 〔解答〕

这里仅列出主程序段:

mov ax,0040h ;送段地址

mov ds, ax

xor si, si ;偏移量地址

xor cx, cx ;计数(循环次数)

xor dx, dx ;空格计数器清零

again: cmp [si], 20h ;与空格的ASCII码比较

jne next ;不是空格,转

inc dx ;是空格,空格数加1

next: inc si ;修改地址指针

汇编语言程序设计(第四版)第4章【课后答案】,

loop again ;cx=cx-1,如cx=0 退出循环

.exit 0

end

〔习题4.12〕编程实现把键入的一个字符,用二进制形式(0 / 1)显示出它的ASCII代码值。

〔解答〕

.model small

.stack 256

.data

stri1 db 'please input',0dh,0ah,'$'

.code

.startup

mov dx,offset stri1

mov ah,09h

int 21h

mov ah, 01h

int 21h

mov cx, 8

again: xor dl,dl

shl al, 1

adc dl, '0'

mov ah,02h

int 21h

loop again

.exit 0

end

〔习题4.13〕编写程序,要求从键盘接收一个数bellN(0 ~ 9),然后响铃bellN次。 〔解答〕

.model small

.stack

.data

stri1 db 'please input number:1--9',0dh,0ah,'$'

.code

.startup

again: mov dx,offset stri1 ;显示stri1,提示输入

mov ah,09h

int 21h

mov ah,01h ;调用输入一个字符

int 21h ;输入一个字符存在al中

cmp al, '1' ;判该字符,如不在 1 -- 9

jb again ;重新输入

cmp al, '9'

汇编语言程序设计(第四版)第4章【课后答案】,

and al,0fh ;在 1 -- 9 ,屏蔽高4位

mov cl, al ;振铃次数送cx

xor ch,ch

abc: mov dl, 07h ;调用一次振铃

mov ah, 02h

int 21h

loop abc

.exit 0

end

〔习题4.14〕编写程序,将一个包含有20个有符号数据的数组arrayM分成两个数组:正数数组arrayP和负数数组arrayN,并分别把这两个数组中的数据个数显示出来。 〔解答〕

.model small

include io.inc

.stack

.data

arrayM db 1,2,3,4,5,6,0,-3,-5,-6,0,7,6,90,-18,-23,34,7,9,8 ;源数组

arrayP db 20 dup(?) ;正数数组

arrayN db 20 dup(?) ;负数数组

dispP db 'Plus Number: ','$'

dispN db 0dh,0ah,'Negs Number: ','$'

.code

.startup

mov cx, 20 ;源数组元素数

xor bx, bx ;设bh为正数个数,bl为负数个数,均清零

xor si, si ;源数组地址位移量

again: ;循环20次

mov ax, arrayM[si] ;取一个元素

cmp ax,0 ;判正数

jl Neg

inc bh ;是,正数个数加1

jmp next

Neg: inc bl ;否,负数个数加1

next: inc si ;修改位移量

loop again ;循环次数减1

mov ah,09h ;调用显示字符串功能

mov dx, offset dispP ;显示个数

int 21h

mov al,bh

call dispuib ; 调用I/O子程序库中的子程序

mov ah,09h ;调用显示字符串功能

mov dx, offset dispN ;显示个数

汇编语言程序设计(第四版)第4章【课后答案】,

mov al,bl

call dispuib ; 调用I/O子程序库中的子程序

.exit 0

end

〔习题4.15〕编写计算100个正整数之和的程序。如果和不超过16位字的范围(65535),则保存其和到wordsum,如超过则显示 overflow 。

〔解答〕

.model small

.stack

.data

num equ 100

wlist dw num dup(?)

wordsum dw ?

error db 'overflow. $'

.code

.startup

mov bx,offset wlist

mov cx,num

xor ax,ax

again: add ax,[bx]

jc next

inc bx

inc bx

loop again

mov [bx],ax

jmp done

next: mov dx,offset error

mov ah,9

int 21h

done: .exit 0

end

〔习题4.16〕编程判断主存0070h:0开始的1KB中有无字符串 DEBUG 。这是一个字符串包含的问题,可以采用逐个向后比较的简单算法。

〔解答〕

.model small

.stack

.data

disp1 db 'There is DEBUG in the aera!' ,0dh,0ah, $'

disp2 db 'There is no DEBUG in the aera!' ,0dh,0ah, $'

.code

.startup

汇编语言程序设计(第四版)第4章【课后答案】,

mov ax, 0070h ;送段地址

mov ds, ax

xor si, si ;地址指针清零

mov cx,1024

cmp [si], 'D' ;与 D'比较

jne next ;不是,转

inc si ;是,地址增1

cmp [si], 'E' ;同上

jne next

inc si

cmp [si], 'B'

jne next

inc si

cmp [si], 'U'

jne next

inc si

cmp [si], 'G'

je yes ;是 DEBUG',转

next: inc si ;不是,地址增1

loop again ;循环

no: mov dx, offset disp2 ;没找到,显示disp2

jmp dsp

yes: mov dx, offset disp1 ;找到,显示disp1

dsp: mov ah, 09h

int 21h

.exit 0

end

〔习题4.17〕编程把一个16位无符号二进制数转换成为用8421BCD码表示的5位十进制数。转换算法可以是:用二进制数除以10000,商为“万位”,再用余数除以1000,得到“千位”;依次用余数除以100、10和1,得到“百位”、“十位”和“个位”。

〔解答〕

.model small

.stack 256

.data

var dw 3546

dbcd db 5 dup(?)

.code

.startup

mov ax, var

mov bx, 10000

mov cl, 10

xor si, si

xor dx, dx

汇编语言程序设计(第四版)第4章【课后答案】,

again: div bx

mov dbcd[si], al

inc si

xchg ax, bx

div cl

xchg ax, bx

cmp si,5

jnz again

.exit 0

end

〔习题4.18〕没有。。。

〔习题4.19〕--

〔习题4.20〕--

〔习题4.21〕--

〔习题4.22〕过程定义的一般格式是怎样的?子程序入口为什么常有PUSH指令、出口为什么有POP指令?下面的程序段有什么不妥吗?若有,请改正:

crazy PROC

push ax

xor ax,ax

xor dx,dx

again: add ax,[bx]

adc dx,0 inc bx inc bx loop again

ret

ENDP crazy

〔解答〕

crazy PROC ;crazy PROC

push ax ;

xor ax,ax ; xor ax,ax

xor dx,dx ; xor dx,dx

again: add ax,[bx] ;again: add ax,[bx]

adc dx,0 ; adc dx,0

inc bx ; inc bx

inc bx ; inc bx

loop again ; loop again

ret ; ret

ENDP crazy ; crazy ENDP

〔习题4.23〕子程序的参数传递有哪些方法,请简单比较。

〔解答〕

汇编语言程序设计(第四版)第4章【课后答案】,

寄存器、共享变量(公共存储单元)、堆栈

用寄存器传递参数是把参数存于约定的寄存器中,这种方法简单易行,经常采用;

用变量传递参数是主程序与被调用过程直接用同一个变量名访问传递的参数,就是利用变量传递参数。如果调用程序与被调用程序在同一个源程序文件中,只要设置好数据段寄存器DS,则子程序与主程序访问变量的形式相同,也就是它们共享数据段的变量,调用程序与被调用程序不在同一个源文件中,必须利用public/extern进行声明,才能用变量传递参数,利用变量传递参数,过程的通用性比较差,然而,在多个程序段间,尤其在不同程序的模块间,利用全局变量共享数据也是一种常见的参数传递方法;

用堆栈传递参数是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口压入堆栈,主程序弹出堆栈取得它们。

〔习题4.24〕采用堆栈传递参数的一般方法是什么,为什么应该特别注意堆栈平衡问题。 〔解答〕

采用堆栈传递参数的一般方法是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们。因为堆栈采用“先进后出”原则存取,而且返回地址和保护的寄存器等也要存于堆栈,所以要特别注意堆栈平衡问题。

〔习题4.25〕什么是子程序的嵌套、递归和重入?

〔解答〕

子程序中又调用子程序就形成子程序嵌套。

子程序中直接或间接调用该子程序本身就形成子程序递归。

子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。

〔习题4.26〕将例题4.7的大写转换为小写字母写成过程,利用AL作为入口、出口参数完成。

〔解答〕

.model small

.stack 256

.data

stdng db 'HeLLO eveRyboDy ! ' , 0

.code

.startup

mov bx, offset atring

again: mov al, [bx]

call chan ;调用过程

mov [bx] , al

next: inc bx

jmp again

done: .exit 0

chan proc ;大写转换为小写字母的过程

or al, al

jz done

cmp al,'A'

汇编语言程序设计(第四版)第4章【课后答案】,

jb next

cmp al, 'Z' ja next or al, 20h ret

chan endp

end

〔习题4.27〕请按如下子程序说明编写过程:

;子程序功能:把用ASCII码表示的两位十进制数转换为对应二进制数

;入口参数:DH=十位数的ASCII码,DL=个位数的ASCII码

;出口参数:AL=对应的二进制数

〔解答〕

astob proc

and dh, 0fh ;十位数的ASCII码转为二进制数

mov al, dh

mul 10 ;al= 10*dh

and dl, 0fh ;个位数的ASCII码转为二进制数

add al, dl ;al= 10*dh + dl

ret

astob endp

〔习题4.28〕写一个子程序,根据入口参数AL=0/1/2,分别实现对大写字母转换成小写、小写转换成大写或大小写字母互换。欲转换的字符串在string中,用0表示结束。 〔解答〕

Change proc

Push bx ;保护bx

xor bx, bx ;位移量清零

cmp al,0 ;根据入口参数AL=0/1/2,分别处理

jz chan_0

dec al

jz chan_1

dec al

jz chan_2

jmp done

chan_0: mov al,string[bx] ;实现对大写字母转换成小写

cmp al,0

jz done

cmp al, A ;是大写字母

jb next0

cmp al, Z ;是大写字母

ja next0

add al, 20h ;转换

mov string[bx], al

汇编语言程序设计(第四版)第4章【课后答案】,

next0: inc bx ;位移量加1,指向下一字母

jmp chan_0

chan_1: mov al,string[bx] ;实现对小写字母转换成大写

cmp al,0

jz done

cmp al, a ;是大写字母

jb next1

cmp al, z ;是大写字母

ja next1

sub al, 20h ;转换

mov string[bx], al

next0: inc bx ;位移量加1,指向下一字母

jmp chan_1

chan_2: mov al,string[bx] ;实现对大写字母转换成小写

cmp al,0

jz done

cmp al, A ;是大写字母

jb next2

cmp al, Z ;是大写字母

ja next20

add al, 20h ;转换

jmp next2

next20: cmp al, a ;是大写字母

jb next2

cmp al, z ;是大写字母

ja next2

sub al, 20h ;转换

mov string[bx], al

next2: inc bx ;位移量加1,指向下一字母

jmp chan_2

done: pop bx ;恢复bx

ret

change endp

〔习题4.29〕编制一个子程序把一个16位二进制数用十六进制形式在屏幕上显示出来,分别运用如下3种参数传递方法,并用一个主程序验证它。

(1)采用AX寄存器传递这个16位二进制数

(2)采用wordTEMP变量传递这个16位二进制数

(3)采用堆栈方法传递这个16位二进制数

〔解答〕

(1)采用AX寄存器传递这个16位二进制数

.model small

.stack

.data

汇编语言程序设计(第四版)第4章【课后答案】,

.code .startup mov ax,wdata call dispa

.exit 0

;

dispa proc

push cx

push dx

mov cl,4

mov dl,ah

shr dl,cl

call dldisp

mov dl,ah

and dl,0fh

call dldisp

mov dl,al

shr dl,cl

call dldisp

mov dl,al

and dl,0fh call dldisp pop dx pop cx

ret

dispa endp

;

dldisp proc

push ax

or dl,30h

cmp dl,39h

jbe dldisp1

add dl,7

dldisp1: mov ah,2

int 21h

pop ax

ret

dldisp endp

end

(2)采用wordTEMP变量传递这个16位二进制数

.model small

.stack

.data

汇编语言程序设计(第四版)第4章【课后答案】,

wordtemp dw ?

.code

.startup

mov ax,wdata

mov wordtemp,ax

call dispa

.exit 0

;

dispa proc

push cx

push dx

mov cl,4

mov dl,byte ptr wordtemp+1

shr dl,cl

call dldisp

mov dl,byte ptr wordtemp+1

and dl,0fh

call dldisp

mov dl,byte ptr wordtemp

shr dl,cl

call dldisp mov dl,byte ptr wordtemp and dl,0fh call dldisp

pop dx

pop cx

ret

dispa endp

;

dldisp proc

push ax

or dl,30h

cmp dl,39h

jbe dldisp1

add dl,7

dldisp1: mov ah,2

int 21h

pop ax

ret

dldisp endp

end

(3)采用堆栈方法传递这个16位二进制数

.model small

汇编语言程序设计(第四版)第4章【课后答案】,

.data

wdata dw 34abh

.code

.startup

push wdata

call dispa

pop ax ;add sp,2

.exit 0

;

dispa proc

push bp

mov bp,sp

push ax

push cx

push dx

mov ax,[bp+4]

mov cl,4

mov dl,ah

shr dl,cl

call dldisp

mov dl,ah

and dl,0fh

call dldisp

mov dl,al

shr dl,cl

call dldisp

mov dl,al

and dl,0fh

call dldisp

pop dx

pop cx

pop ax

pop bp

ret

dispa endp

;

dldisp proc

push ax

or dl,30h

cmp dl,39h

jbe dldisp1

add dl,7

dldisp1: mov ah,2

汇编语言程序设计(第四版)第4章【课后答案】,

pop ax

ret

dldisp endp

end

〔习题4.30〕设有一个数组存放学生的成绩(0 ~ 100),编制一个子程序统计0 ~ 59分、60 ~ 69分、70 ~ 79分、80 ~ 89分、90 ~ 100分的人数,并分别存放到scoreE、scoreD、score

C、score B及score A单元中。编写一个主程序与之配合使用。

〔解答〕

.model small

.stack

.data

score db 70,86,90,45,60,96,100,0,... ;全班成绩数组

count equ $-score ;总人数

scoreE db ? ;0--59分人数

scoreD db ? ;60--69分人数

scoreC db ? ;70--79分人数

scoreB db ? ;80--89分人数

scoreA db ? ;90--99分人数

.code

.startup

lea bx, score

mov cx, count

again:

mov al,[bx] ;取一个成绩

call tjrs ;调用统计分段人数

inc bx ;调整指针

loog again ;cx-cx-1,cx=0退出循环

.exit 0

tjrs proc ;统计分段人数

cmp al, 60

jae next0 ;al>= 60转

inc scoreE ;al<60,0--59分的人数加1

jmp next4

next0: cmp al, 70

jae next1

inc scoreD

jmp next4

next1: cmp al, 80

jae next2

inc scoreC

jmp next4

next2: cmp al, 90

汇编语言程序设计(第四版)第4章【课后答案】,

inc scoreB

jmp next4

next3: inc scoreA

next4: ret

tjrs endp

end

〔习题4.31〕编写一递归子程序,计算指数函数X n 的值。 〔解答〕

model small

.stack

.data

x dw 5

n dw 6

zish dw ?

.code

.startup

mov bx,x

push bx

mov bx,n

push bx

mov bx,x

call zshhsu

pop zish

add sp,2

.exit 0

zshhsu proc

push bx

push ax

push bp

mov bp,sp

mov ax,[bp+8]

cmp ax,0

jne zshhsu1

inc ax

jmp zshhsu2

zshhsu1: dec ax

push bx

push ax

call zshhsu

pop ax

pop bx

mul bx

汇编语言程序设计(第四版)第4章【课后答案】,

zshhsu2: mov [bp+8],ax

pop bp pop ax pop bx ret

zshhsu endp

end

本文来源:https://www.bwwdw.com/article/omri.html

Top