disp wvar disp dhw1: dhw2: disp
loop dhw1 pop ecx pop ebx ret endp
(3)
; 数据段 word 307281AFH ; 代码段,主程序 push wvar call disp add esp,4 mov al,'H' call dispc ; 代码段,子程序 proc push ebp mov ebp,esp push ebx push ecx mov ecx,8 mov eax,[ebp+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 pop ebp ret endp
; 转换为ASCII码 ; 8位
〔习题4.27〕
配合例题4-11的简单加密解密程序,设计一个输入密码的程序,将输入的若干字符经过适当算法得到一个字节量密码。 〔解答〕
;ex0427.asm key msg0 passw errormsg bufnum buffer
include io32.inc .data byte ?
byte 'Enter your password:',0 byte 50 dup(0)
byte 'Password error, input again!',13,10,0 = 255
byte bufnum+1 dup(0) ; 定义键盘输入需要的缓冲区
- -29
msg1 msg2 msg3 start: again0:
encrypt: again: again1:
byte 'Enter messge: ',0 byte 'Encrypted message: ',0 byte 'Original messge: ',0 .code
mov eax,offset msg0 call dispmsg
mov eax,offset passw ; 设置入口参数EAX call readmsg mov ecx,eax dec ecx xor ebx,ebx mov al,passw[ebx] inc ebx
xor al,passw[ebx] loop again0 mov key,al
mov eax,offset msg1 call dispmsg
mov eax,offset buffer ; 设置入口参数EAX call readmsg push eax mov ecx,eax xor ebx,ebx mov al,key
xor buffer[ebx],al inc ebx dec ecx jnz encrypt
mov eax,offset msg2 call dispmsg
mov eax,offset buffer ; 显示加密后的密文 call dispmsg call dispcrlf ;
mov eax,offset msg0 call dispmsg
mov eax,offset passw ; 设置入口参数EAX call readmsg mov ecx,eax dec ecx xor ebx,ebx mov al,passw[ebx] inc ebx
xor al,passw[ebx] loop again1 cmp key,al jz next
; 与原加密关键字比较 ; 密码相同,则进行解密
; 提示输入解密密码错误
;使用简单的异或方法得到加密关键字 ; 调用输入字符串子程序输入密码 ; 提示输入解密密码
; 等同于指令:loop encrypt ; 处理下一个字符 ; 调用输入字符串子程序 ; 字符个数保存进入堆栈
; ECX=实际输入的字符个数,作为循环的次数 ; EBX指向输入字符 ; AL=加密关键字 ; 异或加密 ; 保存加密关键字 ; 提示输入字符串
;使用简单的异或方法得到加密关键字 ; 调用输入字符串子程序输入密码 ; 提示输入加密密码
mov eax,offset errormsg
- -30
next:
decrypt:
call dispmsg jmp again pop ecx xor ebx,ebx mov al,key
xor buffer[ebx],al inc ebx dec ecx jnz decrypt
mov eax,offset msg3 call dispmsg
mov eax,offset buffer ; 显示解密后的明文 call dispmsg
; 处理下一个字符
; 从堆栈弹出字符个数,作为循环的次数 ; EBX指向输入字符 ; AL=解密关键字 ; 异或解密
〔习题4.28〕
设计一个简单的两个整数的加法器程序。 〔解答〕
;ex0428.asm msg1 msg2 start:
exit 0 end start
mov eax,offset msg2 call dispmsg call readc cmp al,20h je start call readsid add ebx,eax mov al,'=' call dispc mov eax,ebx call dispsid call dispcrlf mov eax,offset msg1 call dispmsg call readsid
mov ebx,eax mov al,'+' call dispc call dispcrlf include io32.inc .data
byte 'Enter the integers:',13,10,0
byte 13,10,'Enter space to continue! Enter any other key to exit!',13,10,0 .code
- -31
〔习题4.29〕
利用十六进制字节显示子程序DISPHB设计一个从低地址到高地址逐个字节显示某个主存区域内容的子程序DISPMEM。其入口参数:EAX=主存偏移地址,ECX=字节个数(主存区域的长度)。同时编写一个主程序进行验证。 〔解答〕
;ex0429.asm in Windows Console var start: dispmem dispm1: dispmem
include io32.inc .data
byte 'This is a test!' .code ; 主程序
mov eax,offset var mov ecx,sizeof var call dispmem exit 0 ; 子程序 proc push ebx mov ebx,eax mov al,[ebx] call disphb mov al,' ' call dispc inc ebx loop dispm1 pop ebx ret endp end start
〔习题4.30〕
将例题4-19分别使用子程序模块、子程序库和子程序库包含方法生成最终可执行文件。 〔习题4. 31〕
区别如下概念:宏定义、宏调用、宏指令、宏展开、宏汇编。
〔解答〕
宏定义:就是对宏进行说明,由一对宏汇编伪指令MACRO和ENDM来完成。 宏调用:宏定义之后的使用。在使用宏指令的位置写下宏名,后跟实体参数。 宏指令:使用宏时,其形式很像指令,所以称为宏指令。 宏展开:在汇编时,汇编程序用对应的代码序列替代宏指令。 宏汇编:指使用宏的方法进行汇编语言程序设计。 〔习题4. 32〕
直接使用控制台输入和输出函数实现例题4-21的功能(不使用READMSG和DISPMSG子程序)。 〔解答〕
〔习题4. 33〕
直接使用控制台输出函数实现某个主存区域内容的显示(习题4.29的功能)。可以改进显示形式,例如每行显示16个字节(128位),每行开始先显示首个主存单元的偏移地址,然后用冒号分隔主存内容。 〔解答〕
- -32