识别参数是不同还是相同的汇编程序。

Assembly program that identifies if parameters are different or same.

您好,我正在处理一个程序集,从技术上讲是 HLA(高级程序集)作业,我是一个需要帮助的错误。这是作业:
编写一个 HLA 汇编语言程序,实现一个函数,该函数正确识别所有参数是否不同,根据是否满足此条件在 EAX 中返回 0 或 1 .此函数应具有以下签名:

procedure allDifferent(x: int16; y: int16; z: int16); @nodisplay; @无框;

下面显示的是示例程序对话。

喂我 X:205
喂我 Y:170
喂我 Z:91
所有不同 returns 正确!

喂我 X:0
喂我 Y:0
喂我 Z:0
allDifferent returns false!

喂我 X:121
喂我 Y:121
喂我 Z:121
allDifferent returns false!

这是我的代码。我的问题是,无论我输入什么数字,它总是 returns "allDifferent returns false!" 谢谢你的帮助。

program allDifferent;
#include( "stdlib.hhf" );
static
iDataValue1 : int16 := 0;
iDataValue2 : int16 := 0;
iDataValue3 : int16 := 0;
iDataValue4 : int16 := 0;


procedure allDiff( x: int16; y : int16; z : int16 ); @nodisplay; @noframe;
static
returnAddress : dword;
temp : int16;

begin allDiff;
pop(returnAddress);
pop(z);
pop(y);
pop(x);
pop(temp);

push(returnAddress);
push(AX);
push(BX);

mov(x, AX);
cmp(y, AX);
je xyequal;
jmp notequal;

xyequal:
mov(y, BX);
cmp(z, BX);
je equal;
jmp notequal;

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

notequal:
mov(1, EAX);
jmp ExitSequence;


ExitSequence:
pop(BX);
pop(AX);
ret();
end allDiff;

begin allDifferent;
stdout.put( "Gimme a X:" );
stdin.get( iDataValue1 );
stdout.put("Gimme a Y:");
stdin.get(iDataValue2);
stdout.put("Gimme a Z:");
stdin.get(iDataValue3);

push( iDataValue1 );
push( iDataValue2 );
push( iDataValue3 );
push( iDataValue4 );
call allDiff;

cmp(EAX, 1);
je ISDIFFERENT;
jmp NOTDIFFERENT;


ISDIFFERENT:
    stdout.put("allDifferent retursn true",nl);
    jmp EndProgram;

NOTDIFFERENT:
    stdout.put("allDifferent retursn false",nl);
    jmp EndProgram;

stdout.newln();

EndProgram:


end allDifferent;
notequal:
mov(1, EAX);         <<- good.
jmp ExitSequence;
:
ExitSequence:
pop(BX);
pop(AX);             <<- not so good.
ret();

仔细看看上面序列中 AX 发生了什么。即使您将它设置为代码中的某个值,您也可以使用 pop 指令 覆盖 该值,将 AX 恢复为您进入该函数时的值。

汇编程序函数通常应该保留和恢复调用者可能正在使用的寄存器,但是 而不是 当您想将该寄存器用于 return 一些有用的部分时信息量。


此外,您的参数没有得到正确处理。你按 {p1, p2, p3, junk} 的顺序推送它们(不知道为什么你有第四个参数,因为你什么都不用)。

但是,在函数中,您按 {x, y, z, temp} 的顺序弹出。现在,因为堆栈是 LIFO(后进先出)结构,映射将是:

junk -> x
p3   -> y
p2   -> z
p1   -> temp

这意味着 x 变量将被设置为某个任意值,而不是您传入的 "real" 参数之一。

如果您不打算使用第四个参数,我建议您去掉它。如果您确实想在某个时候使用它,您将需要关联您的推送和弹出操作,以便获得正确的值。


顺便说一句,您可能还可以通过多种方式使代码更简洁。

首先,没有真正需要使用(或 save/restore)BX,因为 AX 是在本地使用的(在一个小的 mov/cmp 块中)。您可以将 AX 用于 xy 检查和 yz 检查。

其次,您可以去掉很多实际上不需要的跳转。你的算法的伪代码可以归结为一个非常简单的:

    if x and y are same, go to NOTDIFF.
    if y and z are same, go to NOTDIFF.
DIFF:
    set AX to 1
    go to END
NOTDIFF:
    set AX to 0
END:
    return