Reputation: 443
I don't really have a clue of what I'm doing... The goal is to add up all the 1's and if its even say so and if its odd say so a C/C++ section gives the variables that are passed into asm
#include <stdint.h>
#include <stdio.h>
#include <iostream>
using namespace std;
extern "C" {
bool isBitCountEven(int32_t);
}
static int32_t testData[] = {
0x0,
0x1,
0x2,
0x4,
0x8,
0x40000000,
0x80000000,
0x00000002,
0xe,
0xff770001,
0xffeeeeff,
0xdeadbeef,
0xbaddf00d,
0xd00fefac,
0xfaceecaf,
0xffffffff,
0xaaaa5555
};
#define NUM_TEST_CASES (sizeof (testData) / sizeof (*testData))
int main()
{
printf(" ICE#10 \n\n");
for (int i = 0; i < NUM_TEST_CASES; i++) {
printf("isBitCountEven(0x%8x) yields: %s\n", testData[i], isBitCountEven(testData[i]) ? "true" : "false");
}
system("PAUSE");
return 0;
}
And this is my asm. It doesn't output anything. Prologue and epilogue are just things Ive copped and pasted from other work that worked well so disregard those, I know they may be garbage
Here is my asm
.386P ; use 80386 instruction set
.MODEL flat,C ; use flat memory model
printf PROTO C, :VARARG
.DATA ; declare initialzed data here
.STACK ; use default 1k stack space
.CODE ; contains our code
;-------------------PART 1------------------------------------------------------------
;if (the number of 1 bits in the binary representation of val is even)
; return true;
; else
; return false;
; }
;
;--------------------------------------------------------------------------------------
isBitCountEven PROC PUBLIC
PUSH ebp ; save caller base pointer
MOV ebp, esp ; set our base pointer
SUB esp, (1 * 4) ; allocate uint32_t local vars
PUSH edi
PUSH esi
; end prologue
MOV al, [ebp + 8]
;now walk down the variable and count the number of 1
SHIFT:
SHL al, 1
JNC SKIP
INC ebx
SKIP:
loop SHIFT
FINALE: ;see if it adds up to ebx
TEST al, al
JP FALSE
TEST ebx, 1
JZ TRUE
TRUE:
MOV eax,1
POP esi ; start epilogue
POP edi
MOV esp, ebp ; deallocate locals
POP ebp ; restore caller base pointer
RET
FALSE:
MOV eax, 0
POP esi ; start epilogue
POP edi
MOV esp, ebp ; deallocate locals
POP ebp ; restore caller base pointer
RET
isBitCountEven ENDP ; end the procedure
END isBitCountEven
What should I do I am completely lost and am horrible at asm...
Upvotes: 0
Views: 826
Reputation: 64904
It can be simplified quite a bit, mostly by getting rid of all the stack frame business (it's really not necessary, there is no dynamic stack allocation) and by using setcc
instead of branching.
You can count the bits of an int32_t with popcnt
, then test whether the count is even,
isBitCountEven PROC PUBLIC
mov eax, dword ptr [esp + 4]
popcnt eax, eax
test al, 1
setz al ; if the lowest bit of the count is zero, its even
ret
isBitCountEven ENDP
An other simple way it to use the parity flag, but it only checks the parity of the low byte so it takes a bit of reduction first,
isBitCountEven PROC PUBLIC
mov eax, dword ptr [esp + 4]
mov edx, eax
shr eax, 16
xor eax, edx
xor al, ah ; all 4 bytes are now XORed together, parity flag reflects total parity
setpe al ; set al to 1 if parity is even, 0 if odd
ret
isBitCountEven ENDP
Upvotes: 2