Вы хорошо наблюдали за поведением, и вы (в основном?) Правильно относились к ним.
movl $array1, %eax
против movl array1, %eax
: да, первый загрузит eax
с адресом памяти, второй загрузит eax
с 32-битным значением из памяти (с этого адреса).
У меня возникли проблемы с пониманием того, как на самом деле регистрируется содержимое магазина.
Регистры общего назначения, такие как eax
, представляют собой 32-разрядные регистры (на современных 64-разрядных процессорах x86, поддерживающих 64-разрядные, eax
- это младшая 32-разрядная часть rax
, то есть 64-разрядных регистров). Это означает, что регистр содержит 32-битные значения (0 или 1). Ничего больше. Отладчики, если вы не переключите их на другую интерпретацию, обычно будут отображать значения в виде 32-разрядного шестнадцатеричного целого числа без знака, потому что из вывода, такого как шестнадцатеричное 1234ABCD
, вы можете прочитать конкретную комбинацию битов в голове (каждая шестнадцатеричная цифра ровно 4 бита, т.е. B
= 11 = 8 + 2 + 1 = 1011 двоичный), но это не означает, что регистр содержит шестнадцатеричное значение, регистр всего 32 бита, и вы можете интерпретировать их так, как пожелаете (или код).
Чтобы получить доступ к элементам массива с индексом i
, вы можете выбрать разные методы, в вашей задаче суммирования массивов я, вероятно, остановлюсь на вашем исходном коде, используя адреса памяти непосредственно на элементах, но тогда вам понадобится еще один регистр для загрузки фактическое значение, то есть:
# loop initialization
movl $array1, %eax # eax = array1 pointer
movl $array2, %ebx # ebx = array2 pointer
# TODO: set up also some counter or end address
loop_body:
# array1[i] += array2[i];
movl (%ebx), %edx # load value array2[i] from memory into edx
addl %edx, (%eax) # add edx to the array1[i] (value in memory at address eax)
# advance array1 and array2 pointers (like ++i;)
addl $4, %eax
addl $4, %ebx
# TODO: do some loop termination condition and loop
Это позволяет использовать простой код цикла тела и предоставлять один и тот же код суммирования с различными массивами для суммирования.
Другие опции
Вы можете избежать необходимости регистрации по адресу памяти, кодируя его непосредственно в инструкции доступа к памяти, например:
# loop initialization
xorl %ecx, %ecx # ecx = 0 (index + counter)
loop_body:
# array1[i] += array2[i];
movl array2(,%ecx,4), %eax # load value array2[i] from memory into eax
addl %eax, array1(,%ecx,4) # add eax to the array1[i]
incl %ecx # ++i
# TODO: do some loop termination condition and loop
Но этот код нельзя перенаправить в разные массивы.
Или вы можете использовать адреса массивов в регистрах, но избегать их изменения, используя адресацию регистров индекса:
# loop initialization
movl $array1, %eax # eax = array1 pointer
movl $array2, %ebx # ebx = array2 pointer
xorl %ecx, %ecx # ecx = 0 (index + counter)
loop_body:
# array1[i] += array2[i];
movl (%ebx,%ecx,4), %edx # load value array2[i] from memory into edx
addl %edx, (%eax,%ecx,4) # add edx to the array1[i]
incl %ecx # ++i
# TODO: do some loop termination condition and loop
Это может иметь смысл, если вы все равно планируете использовать значение индекса, поэтому вам нужен простой i
, и вы планируете использовать адреса массивов позже, поэтому не нужно их модифицировать, и т. Д ...
Существуют и другие способы доступа к значениям в памяти, но описанные выше наиболее просты для тех, кто изучает сборку x86.
Имейте в виду, что в сборке нет переменных или массивов и т. Д. Память компьютера похожа на один огромный массив без имени с индексами от 0 до N-1 (N = размер физической памяти) и на каждом индексе доступен один байт (8 бит информации).
Регистры представляют собой 8/16/32/64 бит информации, доступной непосредственно на микросхеме ЦП, поэтому ЦПУ не нужно знать адрес (имя «eax» похоже на адрес) и не нужно обратитесь к микросхеме памяти для получения значения (поэтому регистры работают быстрее, чем память).
Чтобы связаться с памятью в синтаксисе AT & T, вы должны написать что-то в виде: displacement(base_reg, index_reg, scale)
, посмотрите этот вопрос с деталями: Пара вопросов о [base + index * scale + disp]