mov ebx,offset writebuf ;ebx指向显示缓冲区 test ax,ax jnz write1
mov byte ptr [ebx],30h inc ebx jmp write5
write1: ;若不为0则首先判断是正是负 jns write2 ;若为正则跳过下面两步到write2 mov byte ptr [ebx],'-' inc ebx neg ax write2:
mov cx,10
push cx ;将cx=10压入栈,作为退出标志
write3: ;write3是让eax循环除以10并把余数的ASCII码压入栈 cmp ax,0 jz write4 xor dx,dx div cx add dx,30h push dx jmp write3
write4: ;余数的ASCII码出栈,遇到10终止并转到write5显示结果 pop dx cmp dx,cx jz write5
mov byte ptr [ebx],dl inc ebx jmp write4
write5: ;显示结果 mov byte ptr [ebx],0 mov eax,offset writebuf call dispmsg pop edx pop ecx pop ebx ret write endp
〔习题4.24〕
参考例题4-17,编写实现32位无符号整数输入的子程序,并设计一个主程序验证。 〔解答〕
count array temp readbuf errmsg msg1 msg2
; 数据段 =10
dword count dup(0) dword ? byte 30 dup(0)
byte 'Input error,enter again!',13,10,0
byte 'Input ten unsigned numbers,each number ends with enter key:',13,10,0 byte 'Check the numbers your inputted:',13,10,0
- -25
; 代码段,主程序
mov eax,offset msg1 call dispmsg mov ecx,count mov ebx,offset array again:
call read mov eax,temp mov [ebx],eax add ebx,4 dec ecx jnz again
mov eax,offset msg2 call dispmsg
mov edx,offset array mov ecx,count next:
mov eax,[edx] call dispuid call dispcrlf add edx,4 dec ecx jnz next
; 代码段,子程序
read proc push eax push ecx push ebx push edx read0:
mov eax,offset readbuf call readmsg test eax,eax jz readerr cmp eax,12 ja readerr
mov edx,offset readbuf xor ebx,ebx xor ecx,ecx mov al,[edx] cmp al,'+' jz read1 cmp al,'-' jnz read2 jmp readerr read1: inc edx mov al,[edx] test al,al
26
- - jz read3 ;如果为0,则说明该字符串已结束 read2:
cmp al,'0' jb readerr cmp al,'9' ja readerr sub al,30h
imul ebx,10 ;ebx用来存储处理过的数据 jc readerr movzx eax,al add ebx,eax jnc read1 readerr:
mov eax,offset errmsg call dispmsg jmp read0 read3:
mov temp,ebx pop edx pop ebx pop ecx pop eax ret read endp
〔习题4.25〕
编写一个计算字节校验和的子程序。所谓“校验和”是指不记进位的累加,常用于检查信息的正确性。主程序提供入口参数,有数据个数和数据缓冲区的首地址。子程序回送求和结果这个出口参数。 〔解答〕
checksum sum:
checksum
; 计算字节校验和的通用过程
; 入口参数:DS:EBX=数组的段地址:偏移地址,ECX=元素个数 ; 出口参数:AL=校验和
; 说明:除EAX/EBX/ECX外,不影响其他寄存器 proc xor al,al add al,[ebx] inc ebx loop sum ret endp
; 累加器清0 ; 求和
; 指向下一个字节
〔习题4.26〕
编制3个子程序把一个32位二进制数用8位十六进制形式在屏幕上显示出来,分别运用如下3种参数传递方法,并配合3个主程序验证它。
(1)采用EAX寄存器传递这个32位二进制数 (2)采用temp变量传递这个32位二进制数 (3)采用堆栈方法传递这个32位二进制数 〔解答〕
(1)
wvar
; 数据段 word 307281AFH
- -27
disp dhw1: dhw2: disp
; 代码段,主程序 mov eax,wvar call disp mov al,'H' call dispc ; 代码段,子程序 proc push ebx push ecx mov ecx,8 rol eax,4 mov ebx,eax and al,0fh add al,30h cmp al,'9' jbe dhw2 add al,7 call dispc mov eax,ebx loop dhw1 pop ecx pop ebx ret endp
; 转换为ASCII码 ; 8位
(2)
wvar temp disp dhw1: dhw2:
; 数据段 word 307281AFH word ?
; 代码段,主程序 mov eax,wvar mov temp,eax call disp mov al,'H' call dispc ; 代码段,子程序 proc push ebx push ecx mov ecx,8 mov eax,temp rol eax,4 mov ebx,eax and al,0fh add al,30h cmp al,'9' jbe dhw2 add al,7
call dispc ; 显示一个字符 mov eax,ebx
; 转换为ASCII码 ; 8位
- -28