我的程序接受4个整数,并将它们显示给用户。在打印值时,我没有得到预期的结果。我用的是MASM和Kip的Irvine32库
我的代码是:
include irvine32.inc
.data
msg byte "Enter a number",0
arr dword 4 dup(?)
len=($-arr)/4
.code
main PROC
mov edx,offset msg
call writestring
call crlf
mov eax,0
mov ecx,0
.while(ecx<len)
call readdec
mov arr[ecx],eax
inc ecx
.endw
mov ebx,0
mov ecx,0
.while(ecx<len)
mov ebx,arr[ecx]
call writedec
call crlf
inc ecx
.endw
exit
main ENDP
END main我的程序的示例运行:
Enter a number
1
2
3
4
4
4
4
4在输入数字1、2、3和4之后,程序应该将这些数字显示给用户。我期望的产出是:
Enter a number
1
2
3
4
1
2
3
4如果修改打印数字的循环,以便将要打印的值放在EAX中而不是EBX中,则使用以下代码:
mov eax,arr[ecx]
call writedec最后,我得到了这样的无意义的输出值:
Enter a number
1
2
3
4
67305985
262914
1027
4为什么我的程序是这样的行为,我如何修改它,以获得预期的结果?
发布于 2015-11-11 17:36:04
代码中只有一个真正的问题出现在不同的地方。当你做这样的事情时:
.while(ecx<len)
call readdec
mov arr[ecx],eax
inc ecx
.endw您必须认识到,arr[ecx]与arr+ecx是相同的。ECX是以字节为单位添加到arr中的偏移量。问题是arr的每个元素都是32位(4个字节),因为您将数组声明为:
arr dword 4 dup(?)您需要做的是将ECX乘以每个元素的长度(在本例中为4个字节)。您可以通过将ECX乘以数组arr[ecx*4] = arr+(ecx*4)中元素的大小来做到这一点。这种形式的缩放寻址只支持在32位代码中乘以1、2、4和8的值.您的代码应该如下所示:
.while(ecx<len)
call readdec
mov arr[ecx*4],eax
inc ecx
.endw调用writedec的代码也存在类似的问题。同样,writedec使用EAX中要打印的数字,而不是EBX。此代码:
.while(ecx<len)
mov ebx,arr[ecx]
call writedec
call crlf
inc ecx
.endw应该是这样的:
.while(ecx<len)
mov eax,arr[ecx*4]
call writedec
call crlf
inc ecx
.endw在MASM中获取数组长度的另一个技巧是使用lengthof伪操作码。你在哪里写道:
len=($-arr)/4你可以用:
len=lengthof arr长度将返回arr中的元素数。MASM考虑到每个元素大小(在本例中是4,因为您用DWORD元素声明了arr )。你这样做没什么不对的,我提供另一个机制。
我强烈建议学习如何使用调试器来逐步完成代码。调试器可以是一个非常宝贵的工具,它可以让您查看代码中的进展情况,并查看寄存器和内存中任何给定时间的内容。
https://stackoverflow.com/questions/33648904
复制相似问题