2015-11-11 21 views
1

我的程序接受4个整数,并假设将它们显示给用户。打印这些值时,我没有得到预期的结果。我使用MASM与硖的Irvine32 library使用带有Irvine32库的MASM打印阵列

我的代码是:

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程序应该将这些数字显示给用户。我期望的输出是:

mov eax,arr[ecx] 
    call writedec 

Enter a number 
1 
2 
3 
4 
1 
2 
3 
4 

如果我修改输出数字回路,使我把价值在EAX而不是EBX这个代码打印我结束了像这样荒谬的输出值:

Enter a number 
1 
2 
3 
4 
67305985 
262914 
1027 
4 

为什么我的程序如此行事,我怎么能修改它以获得预期的结果?

+0

是什么让你认为'writedec'需要在'ebx'中输入? – Michael

+0

@Micheal我在第二个循环中使用了eax,但它打印了一些非常长的值。所以我用ebx代替。 –

回答

1

代码中出现在不同的地方只有一个实际问题。当你做这样的事情:

.while(ecx<len) 
    call readdec 
    mov arr[ecx],eax 
    inc ecx 
.endw 

你必须认识到,arr[ecx]相同arr+ecxECX是添加到arr的字节偏移量。问题是,ARR的每个元素都是因为你声明数组作为32位(4个字节):

arr dword 4 dup(?) 

你需要做的是乘法ECX每个元素的长度(以这种情况下4个字节)。您可以通过将ECX乘以阵列中元素的大小arr[ecx*4] = arr+(ecx*4)来完成此操作。这种形式的scaled addressing只支持在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 

lengthof将返回ARR元素的数量。 MASM考虑了每个元素大小的大小(在这种情况下为4,因为您声明了DWORD元素)。你做这件事的方式没有错,我提供了另一种机制。

我强烈建议学习使用调试器来遍历代码。调试器可以是一个非常宝贵的工具,它可以让您看到代码中的进展情况,以及在任何给定时间查看寄存器和内存中的内容。