3.34 解:
array count result
checksum sum:
checksum 3.35 解: ⑴
wdata
dispa
;数据段
db 12h,25h,0f0h,0a3h,3,68h,71h,0cah,0ffh,90h ;数组 equ $-array ;数组元素个数 db ? ;校验和 ;代码段
mov bx,offset array ;BX←数组的偏移地址 mov cx,count ;CX←数组的元素个数 call checksum ;调用求和过程 mov result,al ;处理出口参数 mov ax,4c00h int 21h
;计算字节校验和的通用过程
;入口参数:DS:BX=数组的段地址:偏移地址,CX=元素个数 ;出口参数:AL=校验和
;说明:除AX/BX/CX外,不影响其他寄存器 proc
xor al,al ;累加器清0 add al,[bx] ;求和 inc bx ;指向下一个字节 loop sum ret endp end
.model small .stack .data dw 34abh .code .startup mov ax,wdata call dispa .exit 0 ; 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
dispa
dldisp
dldisp1:
dldisp ⑵
wdata wordtemp
dispa
call dldisp mov dl,al and dl,0fh call dldisp pop dx pop cx ret endp ; proc push ax or dl,30h cmp dl,39h jbe dldisp1 add dl,7 mov ah,2 int 21h pop ax ret endp end
.model small .stack .data dw 34abh dw ? .code .startup mov ax,wdata mov wordtemp,ax call dispa .exit 0 ; 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
dispa
dldisp
dldisp1:
dldisp ⑶
wdata
dispa
pop cx ret endp ; proc push ax or dl,30h cmp dl,39h jbe dldisp1 add dl,7 mov ah,2 int 21h pop ax ret endp end
.model small .stack .data dw 34abh .code .startup push wdata call dispa pop ax .exit 0 ; 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
;add sp,2
pop bp 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.36 解:
如果利用共享变量传递函数,且变量定义和使用不在同一个源程序中,需要利用PUBLIC、EXTERN声明。
3.37宏是如何定义、调用和展开的? 解:
(1)宏定义由一对宏汇编伪指令MACRO和ENDM来完成,格式如下: 宏名 MACRO [形参表] ?? ;宏定义体 ENDM 宏定义之后就可以使用它,即宏调用: 宏名 [实参表]
(2)宏调用的格式同一般指令一样:在使用宏指令的位置写下宏名,后跟实体参数;如果有多个参数,应按形参顺序填入实参,也用逗号分隔
(3)宏展开:在汇编时,宏指令被汇编程序用对应的代码序列替代,这就是宏展开 宏展开的具体过程是:当汇编程序扫描源程序遇到已有定义的宏调用时,即用相应的宏定义体完全替代源程序的宏指令,同时用位置匹配的实参对形参进行取代 3.38 解:
宏调用的参数通过形参、实参结合实现传递,简捷直观、灵活多变。宏汇编的一大特色是它的参数。宏定义时既可以无参数,也可以有一个或多个参数;宏调用时实参的形式也非常灵活,可以是常数、变量、存储单元、指令(操作码)或它们的一部分,也可以是表达式;只要宏展开后符合汇编语言的语法规则即可。 3.39 解:
宏:仅是源程序级的简化:宏调用在汇编时进行程序语句的展开,不需要返回;不减小目标程序,执行速度没有改变
通过形参、实参结合实现参数传递,简捷直观、灵活多变
子程序:还是目标程序级的简化:子程序调用在执行时由CALL指令转向、RET指令返回;形成的目标代码较短,执行速度减慢 需要利用寄存器、存储单元或堆栈等传递参数
选择:宏与子程序具有各自的特点,程序员应该根据具体问题选择使用那种方法。通常,当程序段较短或要求较快执行时,应选用宏;当程序段较长或为减小目标代码时,要选用子程序 3.40 答: move macro doprnd,soprnd mov ax,soprnd mov doprnd,ax endm
3.41 答: logical macro lcode,dopd,sopd lcode dopd,sopd endm
例如,如果使用“and ax,[bx]”指令,可以利用该宏定义,写出宏指令如下: logical and,ax,[bx]
3.42 解: utol macro local next cmp al,’A’ ;小于“A”不转换 jb next cmp al,’Z’ ;大于“A”不转换 ja next add al,20h ;是大写字母则转换为小写字母 next: endm
3.43 解:(假设它们都在数据段) movestr macro strn,dstr,sstr mov cx,ds mov es,cx mov cx,strn mov di,offset dstr mov si,offset sstr cld rep movsb ;;重复传送ES:[DI]←DS:[SI] endm