这是我编写的最新一段代码。我想弄清楚几件事。
问题:我想我几乎拥有它,但是它说每个PIN都是有效的,但它不是。这意味着ValidatePIN过程是错误的,但我似乎无法弄明白。有什么建议吗?
非常感谢你的帮助!!!!!
; 32-bit assembly language template
; INCLUDE Irvine32.inc
INCLUDELIB C:\Irvine\Kernel32.lib
INCLUDELIB C:\Irvine\Irvine32.lib
INCLUDE C:\Irvine\Irvine32.inc
pbyte typedef ptr byte ; pointer to bytes
.data
VALID_PIN = 0
PIN_SIZE = 5
minVals byte 5,2,4,1,3 ; globally visible
maxVals byte 9,5,8,4,6 ; globally visible
samplePin_1 byte 6,3,4,4,3 ; valid PIN
samplePin_2 byte 5,2,3,2,4 ; digit 3 is invalid
samplePin_3 byte 5,2,4,5,3 ; digit 4 is invalid
samplePin_4 byte 1,3,4,4,3 ; digit 1 is invalid
ptr1 pbyte samplePin_1 ; points to array samplePin_1
ptr2 pbyte samplePin_2 ; points to array samplePin_2
ptr3 pbyte samplePin_3 ; points to array samplePin_3
ptr4 pbyte samplePin_4 ; points to array samplePin_4
ptr5 pbyte minVals ; points to array minVals
ptr6 pbyte maxVals ; points to array maxVals
ValidPINMsg byte "The PIN is valid ", 0 ;
InvalidPINMsg byte "The PIN is invalid. The invalid digit is ", 0 ;
.code
main proc
mov eax,VALID_PIN ;
mov edi,ptr5
mov ebp,ptr6
mov esi,ptr1
call ValidatePIN ; determine whether or not the PIN is valid
.IF eax == ecx
mov edx,OFFSET ValidPINMsg
call WriteString
call WaitMsg
call Crlf
.ELSE
mov edx,OFFSET InvalidPINMsg
call WriteString
call WriteDec
call WaitMsg
call Crlf
.ENDIF
mov esi,ptr2
call ValidatePIN ; determine whether or not the PIN is valid
.IF eax == ecx
mov edx,OFFSET ValidPINMsg
call WriteString
call WaitMsg
call Crlf
.ELSE
mov edx,OFFSET InvalidPINMsg
call WriteString
call WriteDec
call WaitMsg
call Crlf
.ENDIF
mov esi,ptr3
call ValidatePIN ; determine whether or not the PIN is valid
.IF eax == ecx
mov edx,OFFSET ValidPINMsg
call WaitMsg
call Crlf
.ELSE
mov edx,OFFSET InvalidPINMsg
call WriteString
call WriteDec
call WaitMsg
call Crlf
.ENDIF
mov esi,ptr4
call ValidatePIN ; determine whether or not the pin is valid
.IF eax == ecx
mov edx,OFFSET ValidPINMsg
call WriteString
call WaitMsg
call Crlf
.ELSE
mov edx,OFFSET InvalidPINMsg
call WriteString
call WriteDec
call WaitMsg
call Crlf
.ENDIF
main endp
ValidatePIN PROC
mov ecx,PIN_SIZE
.REPEAT
.IF (esi < edi) || (esi > ebp)
call L1
.ELSE
add esi,1
add edi,1
add ebp,1
.ENDIF
dec ecx
.UNTIL ecx == 0
L1:
mov eax,ecx
ret
ret
ValidatePIN ENDP
END main
答案 0 :(得分:1)
问题#1:您在exit
末尾忘记了main
,ret
末尾忘记了ValidatePIN
问题#2:Irvine32.lib
有一个CRLF-function。在您想要换行的位置插入call CrLf
。
问题#3:通常,函数会在EAX
中返回结果。调用者可以评估EAX
中的此值。在汇编中,您可以自由返回其他寄存器中的其他值。使用Irvine32.lib
,您可以print the value of EAX
decimal
还有其他有用的功能。看看whole help for Irvine32.inc (with frameset)
<强>附录:强>
还有其他问题:
call ValidatePIN ; determine whether or not the PIN is valid
.IF eax == ecx
mov edx,OFFSET ValidPINMsg
...
.ELSE
...
EAX
什么时候应该变得不等于ECX
? ValidatePIN
的最后一条指令是mov eax,ecx
,因此此时EAX
和ECX
始终相等。你的意思是.IF eax == 0
。
mov esi,ptr2
call ValidatePIN ; determine whether or not the PIN is valid
...
最后一个程序(EDI
)修改了 EBP
和call ...
。你必须再次初始化它们。
.IF (esi < edi) || (esi > ebp)
...
ESI
,EDI
和EBP
在这里是指针(即内存地址)不是值。要获取值,您必须用方括号装饰指针。但是你无法在x86-assembly中直接比较内存和内存。下一个问题是保证只比较一个字节而不是双字。 TL; DR:
mov al, byte ptr [esi]
.IF (al < [edi]) || (al > [ebp])
...
AL
是EAX
的最低字节。 MASM现在认识到,您只需要进程字节。
call L1
call
将返回。我想你想在这一点上中止循环。因此:
jmp L1
您不会喜欢无效数字的编号。 ECX
(确定返回EAX
)在循环中倒计时:5-4-3-2-1-0。要获得“计数”,您必须计算(6 - ECX)
,但保持ECX = 0不变。您可以将该字词转换为(-ECX + 6)
。所以,改变
.IF (al < [edi]) || (al > [ebp])
jmp L1
.ELSE
...
到
.IF (al < [edi]) || (al > [ebp])
neg ecx
add ecx, 6
jmp L1
.ELSE
...