2016-10-20 3 views
0

Я только начал изучать собрание, и я застрял теперь ...Не понимаю, как массивы работают на ассемблере

%include 'io.inc' 

global main 

section .text 
main: 
    ; read a 
    mov eax, str_a 
    call io_writestr 
    call io_readint 
    mov [nb_array], eax 
    call io_writeln 

    ; read b 
    mov eax, str_b 
    call io_writestr 
    call io_readint 
    mov [nb_array + 2], eax 
    call io_writeln 

    mov eax, [nb_array] 
    call io_writeint 
    call io_writeln 
    mov eax, [nb_array + 2] 
    call io_writeint 

section .data 
nb_array dw 0, 0 
str_a db 'a = ', 0 
str_b db 'b = ', 0 

Итак, у меня есть массив размера в 2 Эле и когда я пытаюсь напечатать первый элемент, он не печатает правильное значение. Хотя я пытаюсь напечатать второй элемент, он печатает правильное значение. Может ли кто-нибудь помочь мне понять, почему это происходит?

+1

Что такое размер 'eax'? Что такое размер 'dw 0'? И как строка '' a = ''(на' str_a') обращается после второго ввода в память? (используйте отладчик и представление памяти) – Ped7g

+0

@ Ped7g Я использую eax только для вывода, поэтому я перемещаю элементы nb_array в eax, чтобы иметь возможность распечатывать их. –

+0

Какой из моих трех вопросов отвечает на это? Нет ИМО. (вам не нужно объяснять мне свой код, я знаю, что вы сделали, и что вы хотели сделать ... Я пытаюсь научить, как найти эти ошибки в будущем) – Ped7g

ответ

3

Лучший ответ, вероятно, «потому что в сборке нет массивов». У вас есть доступная память компьютера, которая адресуется байтами. И у вас есть несколько инструкций по манипулированию этими байтами либо по одному байту, либо по группам из них, образующим «слово» (два байта) или «dword» (четыре байта) или даже больше (в зависимости от платформы и расширенных инструкций, которые вы используете) ,

Чтобы использовать память в любом «структурированном» виде в сборке: вам нужно написать кусок кода, подобный этому, и требуется, чтобы какая-то практика была достаточно точной и чтобы выявлять все ошибки в отладчике (как только запускать код с правильным выходом не означает многого, если бы вы делали только одно значение ввода, ваша программа выдавала бы правильный номер, но «a =» был бы уничтожен в любом случае - вам лучше всего каждый новый кусок кода пропустить инструкцию по инструкции в отладчик и убедитесь, что все работает так, как ожидалось).

Ошибки в аналогичном коде были настолько распространена, что люди скорее использовал гораздо хуже машинный код, полученный с помощью компилятора Си, как struct и C массивов были намного проще в использовании, не имея для защиты BY_SIZE умножения каждого индекса, и выделяя правильный объем памяти для каждого элемента.

То, что вы видите в результате, - это именно то, что вы сделали с памятью и конкретными байтами (исправить зависит, хотите ли вы, чтобы она работала на номера ввода 16b или 32b, вам либо нужно исправить инструкции, хранящие/считывающие массив для работы с 16b, или исправить распределение массива и смещения, чтобы сопровождать два значения 32b).