dispm6: mov _membuffer[ebx],dl inc ebx and al,0fh or al,30h cmp al,39h jbe dispm7 add al,7
dispm7: mov _membuffer[ebx],al add ebx,2
inc edi ;指向下一个要显示的字节 dec esi jz dispm10 ;没有要显示的内容,退出 loop dispm5
invoke WriteConsole,_outhandle,\\ addr _membuffer,sizeof _membuffer,\\ addr _outsize,0 jmp dispm1
dispm10: invoke WriteConsole,_outhandle,\\ addr _membuffer,sizeof _membuffer,\\ addr _outsize,0 popad dispm11: ret dispmem endp
习题6.7
执行CPUID指令,在消息窗口显示处理器识别字符串,要求该消息窗有OK和Cancel两个按钮。
MessageBoxA proto :dword,:dword,:dword,:dword MessageBox equ
outbuffer byte '本机的处理器是', 12 dup(0),0 outbufsize = sizeof outbuffer-1 .code start: mov eax,0 cpuid ;执行处理器识别指令 mov dword ptr outbuffer+outbufsize-12,ebx mov dword ptr outbuffer+outbufsize-8,edx mov dword ptr outbuffer+outbufsize-4,ecx invoke MessageBox,NULL,addr outbuffer,\\ addr szCaption,MB_OK invoke ExitProcess,NULL
end start
习题6.8
参考5-10,利用MessageBox函数创建的消息窗口显示32位通用寄存器内容。 .686 .model flat,stdcall option casemap:none includelib ..\\lib\\kernel32.lib includelib ..\\lib\%user32.lib ExitProcess proto,:dword exit macro dwexitcode invoke ExitProcess,dwexitcode endm
GetStdHandle proto,:dword WriteConsoleA proto,:dword,:dword,:dword,:dword,:dword WriteConsole equ
MessageBoxA proto,:dword,:dword,:dword,:dword MessageBox equ
dreg32 macro reg32 local dreg1,dreg2 mov eax,reg32 ;;显示reg32寄存器 mov ecx,8 xor ebx,ebx dreg1: rol eax,4 mov edx,eax and dl,0fh add dl,30h ;;转化为相应的ASCII码值 cmp dl,39h ;;区别0~9和A~F数码 jbe dreg2 add dl,7
dreg2: mov rd®32&[ebx+4],dl inc ebx cmp ebx,ecx jb dreg1 endm .data strCaption byte '32位通用寄存器内容',0 rdeax byte 'EAX=00000000, ' rdebx byte 'EBX=00000000, ' rdecx byte 'ECX=00000000, '
rdedx byte 'EDX=00000000',13,10 rdesi byte 'ESI=00000000, ' rdedi byte 'EDI=00000000, ' rdebp byte 'EBP=00000000, ' rdesp byte 'ESP=00000000',13,10,0 _outsize dword $ - rdeax _outhandle dword ? .code start: invoke GetStdHandle,STD_OUTPUT_HANDLE mov _outhandle,eax
mov eax,12345678h mov ebx,0abcdef00h mov ecx,eax mov edx,ebx
mov esi,11111111h mov edi,22222222h mov ebp,esp call dprd exit 0 dprd proc pushad push edx push ecx push ebx
;假设一些数据
dreg32 eax ;显示EAX pop ebx
dreg32 ebx ;显示EBX pop ecx
dreg32 ecx ;显示ECX pop edx
dreg32 edx ;显示EDX dreg32 esi ;显示ESI dreg32 edi ;显示EDI dreg32 ebp ;显示EBP
add esp,36 ;获得进入该子程序前的ESP dreg32 esp ;显示ESP sub esp,36 ;恢复ESP mov eax,offset rdeax
invoke MessageBox ,0 ,eax , addr strCaption,0 popad ret
dprd endp end start
习题6.9
利用获得系统时间函数,将年月日时分秒星期等时间完整地显示出来。可以创建一个控制台程序,也可以创建一个消息窗口程序。
习题6.10
结构数据类型如何说明,结构变量如何定义,结构字段如何引用 略
习题6.11
条件控制伪指令的条件表达式中,逻辑与“&&”表示两者都为真,整个条件才为“真”;逻辑或“||”表示两者之一为真,整个条件就为“真”。对如下两个程序段(var是一个双字变量):
(1)逻辑与条件
.if (var==5)&&(eax!=ebx) Inc eax .endif (2)逻辑或条件
.if (var==5)||(eax!=ebx) Dec ebx .endif
请直接使用处理器指令实现上述分支结构,并比较汇编程序生成的代码序列。 答: (1) Cmp var,5 Jne done Cmp eax,ebx Je done Inc eax Done: (2) Cmp var,5 Je l1
Cmp eax,ebx Je done L1: Dec ebx Done:
习题6.12
对于如下两个程序段: (1)WHILE循环结构 .while eax !=10 Mov [ebx*4],eax Inc eax .endw
(2)UNTIL循环结构 .repeat
Mov [ebx*4],eax Inc eax
.until eax ==10
请直接使用处理器指令实现上述分支结构,并比较汇编程序生成的代码序列。 答: (1) Next:
Cmp eax,10 Je done
Mov [ebx*4],eax Inc eax Jmp next done: (2) Next:
Mov [ebx*4],eax Inc eax Cmp eax,10 Jne next
习题6.13
使用条件控制.if伪指令编写习题4.16程序,并生成完整的列表文件 test dvar,80000000h .if ! ZERO? mov al,'L' .else test dvar,1 .if ! ZERO? mov al,'R' .else mov al,'M'; .endif .endif call dispc