2016-02-27 2 views
0

Нам назначили выполнение массива как код в языке Assembly. Мы используем архитектуру/систему/код Intel x086.Извлечение значений массива в сборке

Код, который мы создали, должен хранить 3, 4, 5 в 3 разных местах памяти, которые мы назвали [i + EAX]. EAX определяет распределения памяти.

Проблема с этим, когда мы извлекаем значения, хранящиеся в ячейках памяти, отмеченные [i + EAX], результирующими значениями являются мусор.

Где мы ошибаемся? 1. Неправильно ли мы добавили EAX? Предположив +1, +4, +8, чтобы обозначить сохранение следующего целого числа в следующую кучу, мы все же дали неправильные ответы. Это все еще мусор. 2. Является ли номер ячейки памяти в hexa или deci? Мы пробовали оба, но отслеживание памяти доказывает, что наш вывод все еще мусор.

Вот код:

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]' и дальше даст вам мусор. Используйте 'resd 10' в разделе .bss, чтобы зарезервировать десять слов с нулевым инициализированным пространством. –

+0

Привет, Питер, спасибо за комментарий. Мы попытались добавить resd 10, да, он стал 0, но значения «4» и «5» по-прежнему недоступны. Что мы делаем не так? –

ответ

3

Вы не сказали, на каком OS/вызове вы используете, поэтому я должен сделать некоторые догадки.

Во-первых, почему вы установили EAX в 1 для первого значения? Вы просто обеспечиваете неравномерный доступ и пропускаете один байт памяти. Установите его на ноль.

Во-вторых, вы не храните значение EAX при звонке _printf. Скорее всего _printf сохраняет свое возвращаемое значение в EAX, поэтому в следующий раз, когда вы добавите 8 до EAX, это будет не 9, но это будет нечто совершенно другое.

Даже если _printf не сохраняет свое возвращаемое значение в EAX, вы не используете следующий dword, который будет равен 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 также при вызове и появлении потом, если вам действительно нужно использовать add (здесь вы этого не делаете).

+0

Мне нравится ваш ответ. Это хорошо и забавно. – zx485

Смежные вопросы