《新版汇编语言程序设计钱晓捷第4章习题答案.doc》由会员分享,可在线阅读,更多相关《新版汇编语言程序设计钱晓捷第4章习题答案.doc(20页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第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 qvarsi mo
2、v byte ptr qvarsi-1,al inc si loop again test al,80h jz ezz mov bl,0ffh jmp done ezz: mov bl,0 done: mov byte ptr qvar7,bl .exit 0 end习题4.2例题4.2如果要求算术左移7位,如何用移位指令实现。 解答思路:可设计外循环体为8个字节左移一次,方法是:最低位字节算术左移一次, 次低位字节至最高位字节依次带 CF 位循环左移一次(内循环共8次),外循环体控制执行7次即可。 .model small .stack 256 .dataqvar dq 1234567887
3、654321h .code .startup mov dx, 7 ;外循环次数 mov ax, byte ptr qvar0 ;最低位字节送axlpp: shl ax, 1 ;最低位字节左移一次,其d7移入CF位 mov si, 1 mov cx, 7 ;内循环次数again: rcl byte ptr qvarsi, 1 ;高位字节依次左移 P50 inc si loop again dec dx jnz lpp .exit 0 .end习题4.3将AX寄存器中的16位数连续4位分成一组,共4组,然后把这4组数分别放在AL、BL、CL和DL寄存器中。 解答思路:设这四组从低位到高位分别放在A
4、L、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存键值 in
5、t 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数码管显示的代码表为: 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显示代码。解答 .mod
6、el small .stack 256 .dataLEDtable DB 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h DB 80h,90h,88h,83h,0c6h,0clh、86h,8ehlednum DB ? .code .startup mov bx, offset LEDtable mov al, lednum xlat ;al中存有对应的LED显示代码 .exit 0 end习题4.6请问第2章例题2.39 / 2.41 / 2.43 / 2.46的分支是单分支、双分支或多分支结构? 解答例题2.43/2.452.47 为单分支结构;2.50为多分支结构
7、。习题4.7分析第2章例题2.40的分支结构,画出流程图。 解答习题4.8如果在例题4.4的table中依次填入msg1 msg8,程序应该怎样修改?解答(1) 将jmp tablebx指令改为:mov dx, tablebx (2) 去掉源程序中:.exit 0-end之间的语句习题4.9编制一个程序,把变量bufX和bufY中较大者存入bufZ;若两者相等,则把其中之一存入bufZ中。假设变量存放的是8位无符号数。 解答 .model small .stack 256 .databufx db ?bufY db ?bufz db ? .code .startup mov al, bufX
8、mov bl, bufY cmp al,bl ja next mov bufZ, bl jmp done next: mov bufZ, aldone: .exit 0 end习题4.10设变量bufX为有符号16位数,请将它的符号状态保存在signX,即:如果X大于等于0,保存0;如果X小于0,保存-1(ffh)。编写该程序。 解答 .model small .stack .databufX dw -7signX db ? .code .startup cmp bufX,0 ;test bufX,80h jl next ;jnz next mov signX,0 jmp donenext:
9、mov signX,-1done: .exit 0 end习题4.11bufX、bufY和bufZ是3个有符号16进制数,编写一个比较相等关系的程序: (1)如果这3个数都不相等,则显示0;(2)如果这3个数中有两个数相等,则显示1;(3)如果这3个数都相等,则显示2。解答 .model small .stack 256 .databufx 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 dlnext1: cmp ax,
10、cx jnz next2 inc dlnext2: cmp bx,cx jnz next3 inc dlnext3: cmp dl,3 jb next4 mov dl,2next4: mov ah,02h ;显示 int 21h .exit 0 end习题4.12分析第2章例题2.42、2.52、2.53的结构,分别画出它们的流程图。 解答2.422.522.53习题4.13例题4.8内外循环次数共是多少?如果要求按从大到小排序,程序如何修改?解答外循环次数是: count-1次 (19次)内循环次数是: (count-1)!次 ( 19! 次)内外循环次数共是 count-1 + (coun
11、t-1)!次 ,即 19+19!次习题4.14串操作指令常要利用循环结构,现在不用串操作指令实现字符串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 d
12、i, al inc si ;修改指针 inc di ;修改指针 loop again ;cx=cx-1,cx=0时退出循环 .exit 0 end 习题4.15不用串操作指令求主存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 ;是空格,空格数加1next: inc s
13、i ;修改地址指针 loop again ;cx=cx-1,如cx=0 退出循环 .exit 0 end习题4.16编程实现把键入的一个字符,用二进制形式(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, 1adc dl, 0 mov ah,02h int 21
14、h loop again .exit 0 end习题4.17编写程序,要求从键盘接收一个数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
15、, 9 ja again 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.18编写程序,将一个包含有20个有符号数据的数组arrayM分成两个数组:正数数组arrayP和负数数组arrayN,并分别把这两个数组中的数据个数显示出来。 解答 .model small include io.inc .stack .dataarrayM db 1,2,3,4,5,6,0,-3,-5,-6,0,7,6,90,
16、-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, arrayMsi ;取一个元素 cmp ax,0 ;判正数 jl Neg inc bh ;是,正数个数加1 jmp next
17、 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 ;显示个数 int 21h mov al,bl call dispuib ; 调用I/O子程序库中的子程序 .exit 0 end习题4.19编写计算100个正整数之和的程序。如果和不超过16位字
18、的范围(65535),则保存其和到wordsum,如超过则显示overflow。 解答 .model small .stack .datanum equ 100wlist dw num dup(?)wordsum dw ?error db overflow. $ .code .startup mov bx,offset wlist mov cx,num xor ax,axagain: add ax,bx jc next inc bx inc bx loop again mov bx,ax jmp donenext: mov dx,offset error mov ah,9 int 21hdon
19、e: .exit 0 end习题4.20编程判断主存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 mov ax, 0070h ;送段地址 mov ds, ax xor si, si ;地址指针清零 mov cx,1024 cmp si, D ;和D比
20、较 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 习
21、题4.21编程把一个16位无符号二进制数转换成为用8421BCD码表示的5位十进制数。转换算法可以是:用二进制数除以10000,商为“万位”,再用余数除以1000,得到“千位”;依次用余数除以100、10和1,得到“百位”、“十位”和“个位”。 解答 .model small .stack 256 .data var dw3546 dbcd db 5 dup(?) .code .startup mov ax, var mov bx, 10000 mov cl, 10 xor si, si xor dx, dx again: div bx mov dbcdsi, al inc si xchg a
22、x, bx div cl xchg ax, bx cmp si,5 jnz again .exit 0 end 习题4.22过程定义的一般格式是怎样的?子程序入口为什么常有PUSH指令、出口为什么有POP指令?下面的程序段有什么不妥吗?若有,请改正: crazy PROC push ax xor ax,ax xor dx,dxagain: 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 ; xo
23、r dx,dxagain: 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子程序的参数传递有哪些方法,请简单比较。 解答寄存器、共享变量(公共存储单元)、堆栈用寄存器传递参数是把参数存于约定的寄存器中,这种方法简单易行,经常采用;用变量传递参数是主程序和被调用过程直接用同一个变量名访问传递的参数,就是利用变量传递参数。如果调用程序和被调用程序在同一个源程序文
24、件中,只要设置好数据段寄存器DS,则子程序和主程序访问变量的形式相同,也就是它们共享数据段的变量,调用程序和被调用程序不在同一个源文件中,必须利用public/extern进行声明,才能用变量传递参数,利用变量传递参数,过程的通用性比较差,然而,在多个程序段间,尤其在不同程序的模块间,利用全局变量共享数据也是一种常见的参数传递方法;用堆栈传递参数是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口压入堆栈,主程序弹出堆栈取得它们。习题4.24采用堆栈传递参数的一般方法是什么,为什么应该特别注意堆栈平衡问题。 解答采用堆栈传递参数的一般方法是主程序将子程序的入口参数压入堆栈,
25、子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们。因为堆栈采用“先进后出”原则存取,而且返回地址和保护的寄存器等也要存于堆栈,所以要特别注意堆栈平衡问题。习题4.25什么是子程序的嵌套、递归和重入? 解答子程序中又调用子程序就形成子程序嵌套。子程序中直接或间接调用该子程序本身就形成子程序递归。子程序的重入是指子程序被中断后又被中断服务程序所调用,能够重入的子程序称为可重入子程序。习题4.26将例题4.7的大写转换为小写字母写成过程,利用AL作为入口、出口参数完成。 解答.model small .stack 256 .data stdng db HeLLO eveRybo
26、Dy ! , 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 jb next cmp al, Z ja next or al, 20h ret chan endp end习题4.27请按如下子程序说明编写过程: ;子程序功能:把用ASCII码表示的两位十进制数转换为对应二进制数 ;入口参数:DH=十位
27、数的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 retastob endp习题4.28写一个子程序,根据入口参数AL=0/1/2,分别实现对大写字母转换成小写、小写转换成大写或大小写字母互换。欲转换的字符串在string中,用0表示结束。 解答Change proc Push bx ;保护bx xor bx,
28、bx ;位移量清零 cmp al,0 ;根据入口参数AL=0/1/2,分别处理 jz chan_0 dec al jz chan_1 dec al jz chan_2 jmp donechan_0: mov al,stringbx ;实现对大写字母转换成小写 cmp al,0 jz done cmp al,A ;是大写字母 jb next0 cmp al,Z ;是大写字母 ja next0 add al, 20h ;转换 mov stringbx, alnext0: inc bx ;位移量加1,指向下一字母 jmp chan_0chan_1: mov al,stringbx ;实现对小写字母转换成大写 cmp al