2015-11-12 13 views
2

Я работаю над сборкой, высокотехнологичной HLA (High Level Assembly), программой. Мне нужно преобразовать этот код C в assemvbly. Вот задание. Запишите языковую программу ассемблера HLA, которая реализует следующую функцию:Программа рекурсивного отдела сборки

процедура recursiveModulo (a: int32; b: int32); @нет дисплея; @noframe;

Эта функция должна возвращать в EAX значение% b на основе рекурсивного подхода. Для простоты предположим, что и a, и b будут больше или равны нулю. Используя рекурсию, вы будете вынуждены манипулировать стеком времени выполнения. Стройте свои решения по следующим формулам:

Здесь предоставляется код C:

int recursiveModulo(int a, int b) 
{ 
    int result = 0; 
    if (a == 0 || b == 0) 
    { 
    result = 0; 
    } 
    else if (b == 1) 
    { 
    result = 0; 
    } 
    else if (a < b) 
    { 
    result = a; 
    } 
    else 
    { 
    result = recursiveModulo(a-b, b); 
    } 
    return(result); 
} 

Вот мой HLA-код:

program RecursiveDivision; 
#include("stdlib.hhf"); 
static 
iDataValue1 : int32 := 0; 
iDataValue2 : int32 := 0; 

procedure recursiveModulo(a: int32; b : int32); @nodisplay; @noframe; 
static 
returnAddress : dword; 


begin recursiveModulo; 

pop(returnAddress); 
pop(a); 
pop(b); 
push(returnAddress); 
push(ECX); 
push(EBX); 


cmp(a, 0); 
je equal; 
jmp checkb; 

checkb: 
cmp(b, 0); 
je equal; 
jmp b1; 

b1: 
cmp(b, 1); 
je equal; 
jmp alessb; 

equal: 
mov(0, EAX); 
jmp ExitSequence; 

alessb: 
mov(a, EBX); 
cmp(b, EBX); 
jg resulta; 
jmp recursive; 

resulta: 
mov(a, EAX); 
jmp ExitSequence; 

recursive: 
mov(a, ECX); 
sub(b, ECX); 
push(ECX); 
push(b); 
call recursiveModulo; 
jmp ExitSequence; 

ExitSequence: 
pop(ECX); 
pop(EBX); 
ret(); 




end recursiveModulo; 

begin RecursiveDivision; 

stdout.put("Give me A",nl); 
stdin.get(iDataValue1); 
stdout.put("Give me B",nl); 
stdin.get(iDataValue2); 
push(iDataValue1); 
push(iDataValue2); 
call recursiveModulo; 
stdout.puti32(EAX); 


end RecursiveDivision; 

Так часть моего кода, который работает правильно это сначала если блок. Для второго блока if, где результат должен быть равен нулю, если b = 1, это то, что он просто возвращает 1 вместо 0. Для третьего условия, где, если a меньше, чем b, я получаю эти странные проблемы, где он работает для некоторых комбинаций чисел , но в другое время он просто возвращает ноль. для блока else, где он должен вызывать функцию рекурсивно, он просто возвращает параметр a. `

+0

Я не знаю, все правила для HLA, но ваше решение выглядит смешно для меня. В частности, вы являетесь «pop (a)» ... где это происходит? Вообще, когда вы пишете рекурсивную процедуру сборки, вы хотите сохранить все в регистрах или поверх стека. Другая вещь, которая выглядит странно, - это нажатие ECX и EBX на вход в функцию, что означает, что вы всегда делаете это в процедуре «листа» вызова, где это, вероятно, вам не поможет. Если целью является использование ECX и EBX, вы можете сделать это на сайте вызова, избегая затрат на это в процедуре листа. –

+0

Чтобы быть справедливым, то, как один управляет сохранением/восстановлением регистров, часто является вопросом * конвенции *. И если вы не заботитесь о производительности, вы должны использовать «предпочтительное соглашение», потому что это ожидают другие читатели вашего кода (ваш проф.). Тот факт, что вы пишете рекурсивное подразделение, уже говорит нам о том, что производительность не является целью, поэтому, возможно, предпочтительное соглашение - это то, что вы хотите. OTOH, обычная причина на практике, что один пишет ассемблер для производительности, поэтому мой персональный радар всегда сфокусирован именно так. –

+0

Да, я согласен с тем, что вы говорите, но я просто следую за тем, что мне нужно сделать для задания. – ecain

ответ

2

POP pops последний вдавлено значение. Вы нажимаете сначала a, затем b, так что вам нужно сначала попсовать b, затем a.

Изменить

pop(a); 
pop(b); 

в

pop(b); 
pop(a);