0

I made a program that can create and call a function that determines if the sum of all three values is odd and then sets DL to one if the sum is odd; otherwise, set DL to zero, but it doesnt work. Could anyone help? It alwyas truns out "sumIsOdd returned true!" Highly appreciate any and all help!

program Odd_Number;
#include( "stdlib.hhf" );

static
value1 : int8;
value2 : int8;
value3 : int8;

procedure oddtest( var value1 : int8; var value2 : int8; var value3 : int8 ); @nodisplay; @noframe; 

static
dReturnAddress : dword;

begin oddtest;

pop( dReturnAddress ); 
pop( AX ); 
pop( BX );
pop( CX ); 
push( dReturnAddress );

mov(0,DX);
add(DX, AX);
add(DX, BX);
add(DX, CX);


sub_repeat:
dec(DX);
dec(DX);
cmp(DX, 0);
jg sub_repeat;
je even_result;

stdout.put("sumIsOdd returned true!");
jmp done;

even_result:
stdout.put("sumIsOdd returned false!");

done:
ret( );
end oddtest;



begin Odd_Number;


stdout.put( "Provide value1:" );
stdin.get(value1);
stdout.put( "Provide value2:" );
stdin.get(value2);
stdout.put( "Provide value3:" );
stdin.get(value3);

mov(value1,AL);
mov(value2,BL);
mov(value3,CL);


push(CX);
push(BX);
push(AX);

call oddtest;

end Odd_Number;

Michael
  • 57,169
  • 9
  • 80
  • 125
Tom
  • 23
  • 3
  • 1
    Why are you using a loop to check for oddness when you could just check the least significant bit using a `test` or `and` instruction? – Michael Aug 05 '23 at 07:32
  • 2
    It looks like you have the wrong operand order for the `add`s. AFAIK HLA uses a `src, dest` order. – Michael Aug 05 '23 at 07:35
  • 1
    In 32-bit code, args are normally passed in dwords on the stack, not 16-bit words. This clunky way to read args with `pop` assumes that your 3 args are packed 16-bit values, unlike the return address which you use a dword for. (And static storage for it, but registers for the args.) Normally you'd just use `mov` relative to the stack pointer to access args, like `mov 4(%esp), %eax` to load the first one (not adding to zero). Then add or XOR the other two into the same register, from ESP+8 and ESP+12. (You only care about the low bit to determine odd/even, so XOR works but is the same speed.) – Peter Cordes Aug 05 '23 at 07:57
  • @PeterCordes I am not the OP, but would you load/add/xor the LSB of the arguments with a smaller operand size than 32 bit? – Sebastian Aug 05 '23 at 09:44
  • 1
    @Sebastian: No, 32-bit operand-size is the most efficient: no false dependencies or partial-register shenanigans. ([Why doesn't GCC use partial registers?](https://stackoverflow.com/q/41573502)). Or you could start with `movzbl 4(%esp), %eax` to do a 1-byte load, then use `xor 8(%esp), %al` with only 1 extra byte of code-size for the first load. Or start with a 32-bit load and use 8-bit adds/xors. If you want to return a `bool`, you can save a byte at the end by just using `and $1, %al` instead of EAX, but if you're branching on it then upper bits don't matter, always `test $1, %al` – Peter Cordes Aug 05 '23 at 11:53

0 Answers0