1、; 教材课课后习题 3-27;编制程序完成两个已知双精度数(4 字节)A 和 B 相加并将结果存入双精度变量单元SUM 中(不考虑溢出) 。;.model small.stack.dataA DD 12345678hB DD 11111111hSUM DD ?.code.startupmov ax ,word ptr A0 ;注意:变量都为双字类型,所以与字类型寄存器相加要临时改变类型mov dx ,word ptr A+2add ax ,word ptr B0adc dx ,word ptr B2mov word ptr SUM0,axmov word ptr SUM2,dx.exit 0E
2、nd; 教材课课后习题 3-28;编制程序完成12H、45H、0F3H、6AH、20H、0FEH、90H、0C8H、57H 和 34H 等 10 个字节数据之和,并将结果存入字节变量 SUM 中(不考虑溢出) 。;.model small.stack.dataX db 1h,1h,01h,1h,1h,01h,1h,01h,1h,1hSUM dw ? ;注意:题目要求是字节类型,不考虑溢出。但这里使用的是字类型.code .startupmov cx,10xor ax,ax ;mov ax,0mov bx,offset xagain: add al,bxadc ah,0 ;将数组中的数据累加到
3、AX,注意 AH 的处理。 inc bxloop againmov SUM,ax.exit 0End; 教材课课后习题 4-10;设变量 bufX 为有符号 16 位数,请将它的符号状态保存在 signX,即:如果 X 大于等于 0,保存 0;如果 X 小于 0,保存-1(ffh) 。编写该程序。;.model small.stack.databufx dw 8111h ;样例数据,可以随便改。但最好分别取正、负数进行测试signx db ?.code .startupmov ax,bufxtest ax,8000h ;测试符号位jnz next1mov signx, 0jmp out1nex
4、t1:mov signx,0ffhout1:mov bl,signx.exit 0End; 教材课课后习题 4-15;不用串操作指令求主存 0040h : 0 开始的一个 64KB 物理段中共有多少个空格?;.model small.stack.data.code.startupmov ax,0040hmov ds,ax ;将段地址 0040 送到DSmov si,0xor bx,bx ;用 BX 计数空格的次数mov cx,0 ;CX 初值为 0,则最多可进行 64K 次循环again: cmp byte ptrsi, jnz doadd bx,1do: inc sidec cxjnz ag
5、ain ;这两句可改为 loop again;程序运行结束后,次数在 BX 中,用R 命令查看 BX 的值即可。.exit 0End; 教材课课后习题 4-16;编程实现把键入的一个字符,用二进制形式(0 / 1)显示出它的 ASCII 代码值。;.model small.stack.data.code.startupmov ah,01hint 21h ;输入一个字符mov bl,al ;因为系统调用要用到 al 寄存器,所以移位时不用 almov cx,8again: shl bl,1 ;向左移位,将最高位移入CF 标志位jc onemov dl,0jmp twoone:mov dl,1tw
6、o:mov ah,02h ;思考一下,如果用单分支如何实现?int 21hloop again.exit 0end; 教材课课后习题 4-18;编写程序,将一个包含有 20 个有符号数据的数组 arrayM 分成两个数组:;正数数组 arrayP 和负数数组 arrayN,并分别把这两个数组中的数据个数显示出来。;.model small.stack.dataarraym db 1,-2,3,-4,5,-6,-7,-8,9,10,11,-12,-13,-14,-15,16,17,-18,19,-20arrayp db 20 dup(?)arrayn db 20 dup(?)p db 0 ;用于
7、计数正数个数n db 0 ;用于计数负数个数.code.startupmov si,offset arraymmov di,offset arraypmov bx,offset arraynmov cx,20cldmov ax,dsmov es,axgo: lodsbtest al,80hjnz arnstosbinc pjmp againarn:xchg bx,di ;用 DI 指向负数数据,因为串指令 STOSB 规定用其作为指针stosbinc nxchg bx,diagain:dec cxjnz go ;可用 LOOP 指令代替;以下代码输入正数的个数mov dl,+ ;提示为正数个数
8、mov ah,2int 21hmov al,pmov ah,0mov bl,10div bl ;余数在 ah,商在 aladd ax,3030hmov dh,ahmov dl,almov ah,2int 21hmov dl,dhmov ah,2int 21h;以下代码输入负数的个数mov dl,- ;提示为正数个数mov ah,2int 21hmov al,nmov ah,0mov bl,10div bl ;余数在 ah,商在 aladd ax,3030hmov dh,ahmov dl,almov ah,2int 21hmov dl,dhmov ah,2int 21h;思考:显示正、负数个数,
9、用子程序如何实现?.exit 0end; 4-19 参考代码。;编写计算 100 个正整数之和的程序。如果和不超过 16 位字的范围(65535) ,;则保存其和到 wordsum,如超过则显示overflow。;.model small.stack.datacount=10 ;本题以十个数为例array dw 1234h,0fff0h,1h,2h,3h,3h,4h,5h,6h,7fhwordsum dw ?string1 db overflow,$.code.startupmov si,offset array mov cx,countcldxor bx,bxagain: lodsw ;也可
10、以不用串操作,采用直接寻址,请思考如何实现add bx,axjc over ;如果发生溢出则显示错误信息,注意:jc 用于无符数,jo 用于带符号数loop againjmp nextover:mov ah,09hmov dx,offset string1int 21hjmp lastnext:mov wordsum,bxlast: .exit 0End; 教材课课后习题 4-27;请按如下子程序说明编写过程: ;子程序功能:把用 ASCII 码表示的两位十进制数转换为对应二进制数 ;入口参数:DH=十位数的 ASCII 码,DL=个位数的 ASCII 码 ;出口参数:AL=对应的二进制数;.
11、model small.stack.datadecimal db 31h,31hbinary db ?.code.startupmov dh,decimal+1 ;设置入口参数mov dl,decimalcall changmov binary,al ;从出口参数取结果.exit 0;功能:把用 ASCII 表示的 2 位十进制数转换为对应的二进制数;入口参数:DH,DL 为两上 ASCII 码表示的十进制数;出口参数:AL 为对就应的二进制数chang proc nearsub dh,30h ;字符型的十进制数转换成数值型数据sub dl,30hmov al,dhmov bl,10 ;十位要
12、乘于 10,再与个位相加mul bladd al,dlretchang endpend; 教材课课后习题 4-28;写一个子程序,根据入口参数 AL=0/1/2,分别实现对大写字母转换成小写、小写转换成大写或大小写字母互换。;欲转换的字符串在 string 中,用 0 表示结束。;.model small.stack.datamsgSource db soure string is:,0dh,0ah,$msgDestination db Destination string is:,0dh,0ah,$msgPrompt db 0dh,0ah,please choose: 0-toLower 1
13、-toUpper 2-exchange,0dh,0ah,$ ;相当于一个菜单source db MASM is great!,0,0dh,0ah,$destination db 20 dup(?),0dh,0ah,$string1 db please input a number(0 ,1,2):,$.code.startup;显示提示信息mov ah,09hmov dx,offset msgSourceint 21h;显示原字符串mov ah,09hmov dx,offset sourceint 21h;显示输入提示信息mov ah,09hmov dx,offset msgPromptint
14、 21hagain:mov ah,01h ;输入选择int 21hcmp al,30h ;判断是不是 0-2 中的数字,如果不是,重新输入jz gooncmp al,31hjz gooncmp al,32hjnz againgoon:and al,0fh ;设定入口参数,注意:约定存储单元不用设定call change ;调用子程序;显示提示信息mov ah,09hmov dx,offset msgDestinationint 21h;显示目的字符串mov ah,09hmov dx,offset destinationint 21h.exit 0;功能:;入口参数:al=0-转换为小写 1-转
15、换为大写 2-大小写互换; source(存储单元) ;入口参数:destination( 存储单元 )change proc ;子程序开始mov si,offset source ;si 指向原串mov di,offset destination ;di 指向目的串cmp al,2h ;根据入口参数 AL,决定做何转换jz exchangecmp al,1hjz toUppertoLower: ;大写字母变成小写字母(输入 0)mov al,sior al,aljz donecmp al,Ajb nextcmp al,Zja nextadd al,20hnext:mov di,alinc s
16、iinc dijmp toLowertoUpper: ;小写字母变成大写字母(输入 1)mov al,sior al,aljz donecmp al,ajb next1cmp al,zja next1sub al,20hnext1:mov di,alinc siinc dijmp toUpperexchange: ;大写字母变小写,小写子母变大写(输入 2)mov al,sior al,aljz donecmp al,Ajb next2cmp al,Zja toadd al,20hjmp next2to:cmp al,ajb next2cmp al,zja next2sub al,20hnex
17、t2:mov di,alinc siinc dijmp exchangedone:retchange endpend; 教材课课后习题 4-29;编制一个子程序把一个 16 位二进制数用十六进制形式在屏幕上显示出来,分别运用如下 3 种参数传递方法,并用一个主程序验证它。 ;(1)采用 AX 寄存器传递这个 16 位二进制数 ;(2)采用 wordTEMP 变量传递这个 16 位二进制数 ;(3)采用堆栈方法传递这个 16 位二进制数; 第一种方法:采用寄存器来传递参数;.model small.stack.datavalue dw 1f3ah.code.startupmov ax,value
18、 ;设定入口参数call number.exit 0;功能:是把给定数的二进制在屏幕上用十六进制输出;入口参数:AX;出口参数:无number proc nearpush cx ;寄存器保护push axpush dxmov cx,4 ;16 位,每 4 个二进制位转换成一个十六进制位,共需要 4 次again:push cx ;保护循环次数 cx,因为进行右移时需要使用寄存器 CLmov cl,4rol ax,clpush ax ;保护 AX,避免一次操作破坏 AX 中的值and al,0fh ;二进制位转换成一个十六进制位add al,30hmov dl,alcmp dl,39hjbe x
19、ianadd dl,7xian: mov ah,02hint 21hpop axpop cxloop againmov ah ,02hmov dl,H;显示十六进制的后缀 Hint 21hpop dx ;寄存器恢复pop axpop cxretnumber endpEnd; 第二种方法:采用约定存储单元来传递参数;.model small.stack.datawordTEMP dw 1f3Ah.code.startupcall number.exit 0;功能:是把给定数的二进制在屏幕上用十六进制输出;入口参数:wordTEMP;出口参数:无number proc nearpush cx ;寄
20、存器保护push axpush dxmov ax,wordTEMP ;取得入口参数mov cx,4 ;16 位,每 4 个二进制位转换成一个十六进制位,共需要 4 次again:push cx ;保护循环次数 cx,因为进行右移时需要使用寄存器 CLmov cl,4rol ax,clpush ax ;保护 AX,避免一次操作破坏 AX 中的值and al,0fh ;二进制位转换成一个十六进制位add al,30hmov dl,alcmp dl,39hjbe xianadd dl,7xian: mov ah,02hint 21hpop axpop cxloop againmov ah ,02hm
21、ov dl,H;显示十六进制的后缀 Hint 21hpop dx ;寄存器恢复pop axpop cxretnumber endpend; 第三种方法:采用堆栈来传递参数;.model small.stack.datavalue dw 1f3ah.code.startupmov ax,valuepush ax ;被显示数 ,即入口参数压入堆栈call number.exit 0;功能:是把给定数的二进制在屏幕上用十六进制输出;入口参数:将被显示的数压入堆栈;出口参数:无number proc nearpush cx ;寄存器保护push axpush dxpush bpmov bp,spmov
22、 ax,bp+10 ;取得入口参数; mov cx,4 ;16 位,每 4 个二进制位转换成一个十六进制位,共需要 4 次again:push cx ;保护循环次数 cx,因为进行右移时需要使用寄存器 CLmov cl,4rol ax,clpush ax ;保护 AX,避免一次操作破坏 AX 中的值and al,0fh ;二进制位转换成一个十六进制位add al,30hmov dl,alcmp dl,39hjbe xianadd dl,7xian: mov ah,02hint 21hpop axpop cxloop againmov ah ,02hmov dl,H;显示十六进制的后缀 Hint 21hpop bp ;寄存器恢复pop dxpop axpop cxret 2 ;注意:参数 2 的目的是保持堆栈平衡。也可以在主程序中通过 add sp,2来实现。number endpend