102、创建一个名为 FindThrees 的过程,如果数组中某处有三个连续的 3,则返回 1;否则返回 0。该过程的输入参数列表包含数组的指针和数组的大小。声明过程时使用带参数列表的 PROC 指令。保留过程修改的所有寄存器(EAX 除外)。编写一个测试程序,用不同的数组多次调用 FindThrees。
以下是符合要求的汇编代码示例:
INCLUDE Irvine32.inc
; 声明 FindThrees 过程的原型
FindThrees PROTO, pArray:PTR DWORD, arraySize:DWORD
.data
; 测试数组 1
array1 DWORD 1, 2, 3, 3, 3, 4, 5
size1 DWORD ($ - array1) / TYPE DWORD
; 测试数组 2
array2 DWORD 1, 2, 3, 4, 5
size2 DWORD ($ - array2) / TYPE DWORD
; 测试数组 3
array3 DWORD 3, 3, 3, 6, 7
size3 DWORD ($ - array3) / TYPE DWORD
.code
main PROC
; 调用 FindThrees 测试数组 1
INVOKE FindThrees, ADDR array1, size1
mov ebx, eax
call WriteInt
call Crlf
; 调用 FindThrees 测试数组 2
INVOKE FindThrees, ADDR array2, size2
mov ebx, eax
call WriteInt
call Crlf
; 调用 FindThrees 测试数组 3
INVOKE FindThrees, ADDR array3, size3
mov ebx, eax
call WriteInt
call Crlf
exit
main ENDP
; FindThrees 过程的实现
FindThrees PROC USES esi ecx, pArray:PTR DWORD, arraySize:DWORD
mov esi, pArray
mov ecx, arraySize
sub ecx, 2 ; 因为要检查连续三个元素,所以循环次数减 2
L1:
mov eax, [esi]
cmp eax, 3
jne Next
mov eax, [esi + 4]
cmp eax, 3
jne Next
mov eax, [esi + 8]
cmp eax, 3
jne Next
mov eax, 1 ; 找到连续三个 3,返回 1
jmp Done
Next:
add esi, 4 ; 移动到下一个元素
loop L1
mov eax, 0 ; 未找到连续三个 3,返回 0
Done:
ret
FindThrees ENDP
END main
上述代码中,首先声明了 FindThrees 过程的原型。在 main 过程中,定义了三个测试数组,并多次调用 FindThrees 过程进行测试。 FindThrees 过程通过循环遍历数组,检查是否存在连续三个 3 的情况,根据结果返回 1 或 0。
103、编写一个名为ShowParams的过程,该过程显示调用它的过程的运行时栈上32位参数的地址和十六进制值。参数应按从最低地址到最高地址的顺序显示。该过程的输入是一个整数,用于指示要显示的参数数量。例如,假设main中的以下语句调用MySample并传递三个参数:INVOKE MySample, 1234h, 5000h, 6543h。然后,在MySample内部,你应该能够调用ShowParams并传递要显示的参数数量:MySample PROC first:DWORD, second:DWORD, third:DWORD paramCount = 3 call ShowParams, paramCount ShowParams应按以下格式显示输出:Stack parameters: --------------------------- Address 0012FF80 = 00001234 Address 0012FF84 = 00005000 Address 0012FF88 = 00006543
以下是实现 ShowParams 过程的示例代码:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
ShowParams PROC paramCount:DWORD
pushad ; 保存所有通用寄存器
mov ecx, paramCount ; 将参数数量存入ECX
mov esi, esp ; 获取当前栈指针
add esi, 4 ; 跳过返回地址
; 显示标题
mov edx, offset title
call StdOut
mov edx, offset line
call StdOut
L1:
; 显示地址
mov edx, offset address_msg
call StdOut
mov eax, esi
call IntToHex
mov edx

630

被折叠的 条评论
为什么被折叠?



