mov [bx],ax .exit 0 end
〔习题4.19〕编写计算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.23〕子程序的参数传递有哪些方法,请简单比较。〔解答〕
寄存器、共享变量(公共存储单元)、堆栈
用寄存器传递参数是把参数存于约定的寄存器中,这种方法简单易行,经常采用; 用变量传递参数是主程序与被调用过程直接用同一个变量名访问传递的参数,就是利用变量传递参数。如果调用程序与被调用程序在同一个源程序文件中,只要设置好数据段寄存器DS,则子程序与主程序访问变量的形式相同,也就是它们共享数据段的变量,调用程序与被调用程序不在同一个源文件中,必须利用public/extern进行声明,才能用变量传递参数,利用变量传递参数,过程的通用性比较差,然而,在多个程序段间,尤其在不同程序的模块间,利用全局变量共享数据也是一种常见的参数传递方法;
用堆栈传递参数是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数;子程序将出口压入堆栈,主程序弹出堆栈取得它们。
〔习题4.24〕采用堆栈传递参数的一般方法是什么,为什么应该特别注意堆栈平衡问题。〔解答〕
采用堆栈传递参数的一般方法是主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序弹出堆栈取得它们。因为堆栈采用“先进后出”原则存取,而且返回地址和保护的寄存器等也要存于堆栈,所以要特别注意堆栈平衡问题。
〔习题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 jae next3 inc scoreB jmp next4 next3: inc scoreA next4: ret tjrs endp end
5.1; cmp X, 5 je abc jmp done abc: cmp ax, bx jne cde jmp done cde: inc ax done:.... 5.2;cmp X, 5 je abc jmp done cmp ax, bx jne abc jmp done abc: inc ax done: .... 5.4;
宏定义采用一对伪指令实现,格式如下(其中方括号表示可选): 宏名 macro [形参表] 宏定义体 endm
宏调用时,利用宏名带上实参即可,格式如下: 宏名 [实参表]