2016-02-27 56 views
0

我们已被分配为在汇编语言中执行类似数组的代码。我们使用英特尔x086架构/系统/代码。检索程序集中的数组值

我们创建的代码应该将3,4,5存储到3个不同的内存位置,我们称之为[i + EAX]。 EAX定义了内存分配。

问题是,当我们检索存储在[i + EAX]指出的内存位置内的值时,结果值是垃圾。

我们在哪里错了? 1.我们错误地添加了EAX吗?假设+1,+ 4,+8表示将下一个整数存储到下一个堆中,我们仍然得出错误的答案。这仍然是垃圾。 2.内存位置编号是六位还是十位?我们尝试了两种方式,但是记忆追踪证明我们的输出仍然是垃圾。

下面的代码:

global _main 
extern _system, _printf 

section .text   

_main: 

; clear screen 
push clr 
call _system 
add esp, 4 

MOV EAX, 0001 
MOV EBX, 0003 

;FIRST - Initialize to 3. 
MOV dword [i+EAX], EBX 
push dword [i+EAX] 
push prompt 
call _printf  
add esp, 8 
ADD EAX, 0008 ; Assuming next memory space will be allocated at 0009 
INC EBX   ; add value, to increase to 4. 

;SECOND - Initialize to 4. 
MOV dword [i+EAX], EBX 
push dword [i+EAX] 
push prompt 
call _printf  
add esp, 8 
ADD EAX, 0008 
INC EBX; 

;THIRD - Initialize to 5. 
MOV dword [i+EAX], EBX 
push dword [i+EAX] 
push prompt 
call _printf  
add esp, 8 

;RETRIEVE FIRST - Which should be "3" 
MOV EAX, 0001 
push dword [i+EAX] 
push prompt 
call _printf  
add esp, 8 

; RETRIEVE SECOND - Which should be "4", but shows garbage value. Why? 
    MOV EAX, 0002 
    push dword [i+EAX] 
    push prompt2 
    call _printf  
    add esp, 8 

    ret 

    section .data 
    clr   db "cls",0 
    prompt db "Value is %d",13,10,0  
    prompt2 db "EAX testing X is %x",13,10,0  
    prompt3 db "EAX testing D is %d",13,10,0  
    i  dd 0 

请帮助我们。谢谢!

+2

我已经在你之前的问题中用基本相同的代码回答了这个问题。 'i'是'dd 0'的标签,它将四个'0'字节组装成数据段。访问超过'[i + 4]'和以后会给你垃圾。在.bss部分使用'resd 10'来保留10个零初始化空间的dword。 –

+0

嗨,彼得,谢谢你的评论。我们尝试添加resd 10,是的,它变成了0,但是仍然无法访问值“4”和“5”。我们做错了什么? –

回答

3

你没有说你正在使用哪种操作系统/调用约定,所以我必须做一些猜测。

首先,您为什么将EAX设置为1作为第一个值?你只需确保一个不对齐的访问并跳过一个字节的内存。将其设置为零。

其次,在拨打_printf时,不存储EAX的值。最有可能的是_printf正在将其返回值存储在EAX中,所以下次当您将8添加到EAX时,它不会是9,但它会是完全不同的东西。

即使_printf没有在EAX中存储其返回值,也没有使用下一个双字,这将是4.另请参见下一点。第三,在打印数值时,突然使用值1和值2作为EAX来访问值i,这当然不会给你两个位于另一个之后的双字组。您将访问完全不同的内存区域。您必须使用相同的值来保存和检索值。

所以,即使EAX没有被修改,你正在以字节i + 1 - i + 4,然后i + 9 - i + 12,然后i + 13 - i + 16存储的东西。然后在打印时,您正在访问字节i + 1 - i + 4和i + 2 - i + 5。正如你所看到的,你永远不会写信给i + 5,因此它将包含垃圾。

明确地将EAX设置为0,4,8等。不要添加任何东西。然后查看存储的内容和输出内容。或者在调用EAX的时候也可以推EAX,如果你真的需要使用add(这里你不需要)。

+0

我喜欢你的答案。它有充分的根据和有趣的。 – zx485