汇编语言程序设计第四版【课后习题答案】--囮裑為檤第4章基本汇编语言程序设计〔习题4.1〕例题4.2如果要求算术右移8位,如何修改程序。
〔解答〕思路:首先由最高位字节向次低位字节传送……次低位字节向最低位字节传送(共7次);再判最高位字节符号位,如为0,送00h到最高位字节;如为1,送ffh到最高位字节。
传送可参考例题4.2,不过应从第一号字节送第零号字节,……最高位字节向次低位字节传送;也可以用循环来完成:.model small.stack 256.dataqvar dq 1234567887654321h.code.startupmov cx,7mov si,1again: mov al, byte ptr qvar[si]mov byte ptr qvar[si-1],alinc siloop againtest al,80hjz ezzmov bl,0ffhjmp doneezz: mov bl,0done: mov byte ptr qvar[7],bl.exit 0end〔习题4.2〕例题4.2如果要求算术左移7位,如何用移位指令实现。
〔解答〕思路:可设计外循环体为8个字节左移一次,方法是:最低位字节算术左移一次,次低位字节至最高位字节依次带CF 位循环左移一次(内循环共8次),外循环体控制执行7次即可。
.model small.stack 256.dataqvar dq 1234567887654321h.code.startupmov dx, 7 ;外循环次数mov ax, byte ptr qvar[0] ;最低位字节送axlpp: shl ax, 1 ;最低位字节左移一次,其d7移入CF位mov si, 1mov cx, 7 ;内循环次数again: rcl byte ptr qvar[si], 1 ;高位字节依次左移P50inc siloop againdec dxjnz 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 ;屏蔽高四位后送almov cl, 4 ;原al中的数据逻辑右移4次送blshr bl, clmov dl, ah ;将ah中的两组分开and dl, 0f0h ;屏蔽低高四位后送dlmov cl, 4 ;原ah中的数据逻辑右移4次送dlshr dl, clmov cl, ah ;屏蔽高四位后送cland cl, 0fh〔习题4.4〕编写一个程序,把从键盘输入的一个小写字母用大写字母显示出来。
〔解答〕getkey: mov ah, 1 ;从键盘输入,出口:al存键值int 21hcmp al, 'a' ;判键值是小写字母?jb getkaycmp al, 'z'ja getkaysub al,20h ;是小写字母转换为大写字母mov dl,almov ah, 02h ;显示int 21h〔习题4.5〕已知用于LED数码管显示的代码表为:.databufX dw -7signX db ?.code.startupcmp bufX,0 ;test bufX,80hjl next ;jnz nextmov signX,0jmp donenext: mov signX,-1done: .exit 0end〔习题4.8〕bufX、bufY和bufZ是3个有符号16进制数,编写一个比较相等关系的程序:(1)如果这3个数都不相等,则显示0;(2)如果这3个数中有两个数相等,则显示1;(3)如果这3个数都相等,则显示2。
〔解答〕.model small.stack 256.databufx dw ?bufY dw ?bufz dw ?.code.startupmov ax, bufXmov bx, bufYmov cx, bufZmov dl, '0'cmp ax,bxjnz next1inc dlnext1: cmp ax,cxjnz next2inc dlnext2: cmp bx,cxjnz next3inc dlnext3: cmp dl,’3’jb next4mov dl,’2’next4: mov ah,02h ;显示.exit 0end〔习题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.datastring1 db 'good morning!'len = $-string1string2 db len dup(?).code.startupmov cx, len ;字符数mov si, offset string1 ;源指针mov di, offset string2 ;目标指针again: mov al, [si] ;送一个字符mov [di], alinc si ;修改指针inc di ;修改指针loop again ;cx=cx-1,cx=0时退出循环.exit 0end〔习题4.11〕不用串操作指令求主存0040h : 0开始的一个64KB物理段中共有多少个空格?〔解答〕这里仅列出主程序段:mov ax,0040h ;送段地址mov ds, axxor si, si ;偏移量地址xor cx, cx ;计数(循环次数)xor dx, dx ;空格计数器清零again: cmp [si], 20h ;与空格的ASCII码比较jne next ;不是空格,转inc dx ;是空格,空格数加1next: inc si ;修改地址指针- 5 -loop again ;cx=cx-1,如cx=0 退出循环.exit 0end〔习题4.12〕编程实现把键入的一个字符,用二进制形式(0 / 1)显示出它的ASCII代码值。
〔解答〕.model small.stack 256.datastri1 db 'please input',0dh,0ah,'$'.code.startupmov dx,offset stri1mov ah,09hint 21hmov ah, 01hint 21hmov cx, 8again: xor dl,dlshl al, 1adc dl, '0'mov ah,02hint 21hloop again.exit 0end〔习题4.13〕编写程序,要求从键盘接收一个数bellN(0 ~ 9),然后响铃bellN次。
〔解答〕.model small.stack.datastri1 db 'please input number:1--9',0dh,0ah,'$'.code.startupagain: mov dx,offset stri1 ;显示stri1,提示输入mov ah,09hint 21hmov ah,01h ;调用输入一个字符int 21h ;输入一个字符存在al中cmp al, '1' ;判该字符,如不在‘1’--‘9’jb again ;重新输入cmp al, '9'and al,0fh ;在‘1’--‘9’,屏蔽高4位mov cl, al ;振铃次数送cxxor ch,chabc: mov dl, 07h ;调用一次振铃mov ah, 02hint 21hloop abc.exit 0end〔习题4.14〕编写程序,将一个包含有20个有符号数据的数组arrayM分成两个数组:正数数组arrayP和负数数组arrayN,并分别把这两个数组中的数据个数显示出来。
〔解答〕.model smallinclude io.inc.stack.dataarrayM 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.startupmov cx, 20 ;源数组元素数xor bx, bx ;设bh为正数个数,bl为负数个数,均清零xor si, si ;源数组地址位移量again: ;循环20次mov ax, arrayM[si] ;取一个元素cmp ax,0 ;判正数jl Neginc bh ;是,正数个数加1jmp nextNeg: inc bl ;否,负数个数加1next: inc si ;修改位移量loop again ;循环次数减1mov ah,09h ;调用显示字符串功能mov dx, offset dispP ;显示个数int 21hmov al,bhcall dispuib ; 调用I/O子程序库中的子程序mov ah,09h ;调用显示字符串功能mov dx, offset dispN ;显示个数- 7 -mov al,blcall dispuib ; 调用I/O子程序库中的子程序.exit 0end〔习题4.15〕编写计算100个正整数之和的程序。
如果和不超过16位字的范围(65535),则保存其和到wordsum,如超过则显示‘overflow’。
〔解答〕.model small.stack.datanum equ 100wlist dw num dup(?)wordsum dw ?error db 'overflow. $'.code.startupmov bx,offset wlistmov cx,numxor ax,axagain: add ax,[bx]jc nextinc bxinc bxloop againmov [bx],axjmp donenext: mov dx,offset errormov ah,9int 21hdone: .exit 0end〔习题4.16〕编程判断主存0070h:0开始的1KB中有无字符串‘DEBUG’。