выглядит хорошо по большей части. Однако после восстановления питания вы должны удалить переменные из стека. В этих обстоятельствах это не имеет значения, поскольку _start не возвращается, но будет иметь значение, если вы попытаетесь вызвать функцию из функции, которая возвращает и не очищает. Адрес возврата функции сохраняется в стеке и извлекается инструкцией ret
, поэтому, если у вас есть что-то еще на вершине стека, вы вернетесь в неправильное место.
_start:
push dword 3
push dword 2
call power
add esp,8 ; Removes two dwords from stack
Если вы пишете функцию, которая вызывает много других функций, лучше выделить место для аргументов стека в начале функции, записать в нее перед каждым вызовом функции и удалить ее из стека в конце функция. Таким образом, вы тратите меньше времени на нажатия и выталкивание, потому что вместо этого вы можете использовать mov
с правильным адресом.
_start:
sub esp,8 ; Make room for two dwords
mov dword [esp+4], 3
mov dword [esp], 2
call power
add esp,8 ; Removes two dwords from stack
Как комментарий к вашей функции питания: в настоящее время она работает, только если мощность не меньше 2. Вы можете изменить минимальную мощность на 0 следующим образом:
- Начните eax с 1
- Не уменьшать переменную счетчика перед циклом
- Проверьте, не равен ли счетчик 0 в начале цикла
Пример:
; dec dword [ebp-8] ; Don't do this
mov eax, dword 1
jmp power_loop
power_loop:
cmp dword [ebp-8], 0
je end_loop
imul eax, dword [ebp-4] ;multiply current val by original num
dec dword [ebp-8] ;decrement counter
jmp power_loop
end_loop:
mov esp, ebp