Прежде всего, в ответ на ваши вопросы:
Как хранить значения в последовательных ячейках памяти?
В MASM32 вы можете либо напрямую сделать mov
, как mov sum_addr, eax
(при условии, что типы данных имеют одинаковый размер), либо вы можете передавать указатели данных. В примере, который я написал, указатель на total
передается функции. Затем функция записывает значение в память, на которую указывает этот указатель (то есть содержимое total
). Не совсем уверен, что вы подразумеваете под последовательными ячейками памяти. Если вы имеете в виду арифметику указателей, я могу показать вам пример этого.
Правильно ли я использую инструкции перехода и метки?
Да, похоже, все в порядке. Альтернативой, которую я использую, являются анонимные ярлыки. Это уместно, когда метка тривиальна и довольно близка. Это личное предпочтение. Если вы считаете, что название метки более уместно, не стесняйтесь использовать его тоже.
Нужно ли использовать определенные регистры, такие как eax, для решения этих проблем? Почему?
MASM32 следует соглашению о вызовах Win32 (stdcall), так что это также хорошо для вас. С точки зрения сохранения регистров это означает, что ожидается, что все функции сохранят регистры, кроме eax
, ecx
и edx
, которые считаются пересылаемыми. Возвращаемые значения сохраняются в eax
или eax
и edx
, если требуется более 4 байтов.
С точки зрения написанного вами кода у вас есть несколько проблем, таких как попытка переместить типы данных разного размера друг в друга. Например, если вы переместите byte
в dword
, вы должны сначала расширить его до того же размера.
mov eax, temp
Это не скомпилируется, потому что temp
имеет длину всего 1 байт, тогда как eax
составляет 4 байта. Вы можете сделать вместо этого:
movzx eax, temp
Это ноль расширяется temp
перед выполнением движения. Вот код, который я собрал вместе, который может научить вас нескольким вещам. Он использует макросы (не уверен, если вы хотите их изучить), но в противном случае демонстрирует идиоматическую передачу параметров MASM32 и возвращаемые значения.
include \masm32\include\masm32rt.inc
.DATA
total DWORD 0 ;Total of all counted numbers
.CODE
; takes in address of total and writes the value there
sum PROC sum_addr:DWORD
xor eax, eax
xor ecx, ecx
@@:
inc ecx
add eax, ecx
cmp ecx, 13
jnz @b
mov edx, sum_addr
mov dword ptr ds:[edx], eax
print ustr$(eax), 13, 10
mov edx, sum_addr
mov eax, dword ptr ds:[edx]
ret
sum ENDP
start:
push offset total ; pass address of total
call sum
print ustr$(eax), 13, 10 ; demonstrating how to use return values
print ustr$(total), 13, 10 ; testing result got stored properly
ret
end start
END
Код не оптимизирован, но должен быть легко понятным. Обратите внимание, как я старался максимально использовать регистры (это более эффективно, чем постоянное обращение с памятью, если у нас достаточно регистров).