2012-03-26 2 views
0

Здравствуйте, я новичок в сборке, и я изо всех сил пытаюсь работать с двухчастной программой. Я использую Visual Studio для этой сборки x86.x86 Assembly Newbie: Основная проблема с добавлением и хранением номеров

часть I) Моя первая цель - подсчитать до 13, добавив каждое значение по пути туда. Ex, 0 + 1 + 2 + 3 ... + 13 = 91. Я хочу сохранить это общее количество в целом.

часть 2) Во-вторых, я хочу подсчитать по степеням 2 от 2^0 до 2^6. Пример: 0,1,2,4,8,32,64. Я думаю * Я делаю это, но я не храню каждое значение, поскольку я иду. Я хочу сохранить их в последовательных ячейках памяти.

меня это до сих пор,

.586 
.MODEL FLAT 

.STACK 4096 

.DATA 
num1 BYTE 13   ;Initialize number to count to 
totall BYTE 0   ;Total of all counted numbers 
temp BYTE 0   ;Temp for loop adding 

shiftme BYTE 1  ;Start of counting 2^0 so I can reach 2^6 

.CODE 
main PROC 
;code here 

increment:   ;Increment label 
inc temp    ;Increment temp by 1 
mov eax, temp 
add totall, eax  ;Add temp+totall and store in totall 
cmp eax, num1   ;Compare for jump 
jne increment   ;Jump if not equal 

;this part should store each value 1,2,4,8,32.. in consecutive memory locat 
shiftallthethings: ;Shift label 
shl shiftme, 1  ;Shifting bits to the left one 
cmp shiftme, 64  ;Comparing for the jump 
jne shiftallthethings ;Jump if not equal to 

ret 
main ENDP 
END 

Вопросы, чтобы помочь мне понять.

  • Как хранить значения в последовательных ячейках памяти?
  • Правильно ли я использую инструкции по прыжкам и этикеткам?
  • Нужно ли использовать определенные регистры, такие как eax, для выполнения этих проблем? Зачем?

Любая помощь ВЕЛИКОЕ оценили, спасибо.

+1

Что означает сохранение значений в последовательных ячейках памяти? Можете ли вы дать конкретную проблему для нас решить? Также используется как MASM32. –

+0

@MikeKwan Я не совсем уверен, что это значит, если мы проигнорируем этот момент, как мы храним shiftme каждый раз, когда он снова и снова перескакивает на ярлык. Также этот код имеет смысл для решения проблем, которые я опубликовал? – KRB

+0

'add totall, temp' и' cmp temp, num1' неверны, потому что 'add' и' cmp' не могут иметь оба операнда в памяти. Действительные комбинации: регистр + память или память + регистр, регистр + немедленная константа, память + немедленная константа. Вы должны использовать регистр здесь. –

ответ

2

Прежде всего, в ответ на вопросы:

Как значения один магазин в последовательных ячейках памяти?

В 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 

Код не оптимизирован, но должен быть легко понятным. Обратите внимание, как я старался использовать регистры как можно больше (это более эффективно, чем при работе с памятью, если у нас достаточно регистров).

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

  • Нет связанных вопросов^_^