2017-04-07 1 views
0

나는 내가하고있는 것에 대한 단서를 가지고 있지 않다. ... 목표는 모든 1을 더하고 심지어 그것의 이상이 그렇게 말한다면 는 C는/C++ 섹션에서는 ASMx86 어셈블리의 모든 1 비트를 더한다

#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; 
} 

로 전달되는 변수를 제공합니다 그리고 이것은 내 ASM이다. 아무것도 출력하지 않습니다. 프롤로그와 에필로그는 필자가 자백 그래서 사람들을 무시 잘 작동 다른 작업에서 붙여 넣기 단지 것들, 나는 그들이 쓰레기 여기

내 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 

나는 완전히 잃어버린 나는 어떻게해야합니까 그리고 끔찍한 asm에서 ...

+0

모든 짝수 값과 비교할 필요는 없으며 단지 'test ebx, 1 \ jz even'을 사용할 수 있습니다. 'loop'를 사용하지 마십시오. 그리고'convert to binary '라는 줄은 여러 가지 의미가 없다. (이미 바이너리이고, 명령어가 변환하지 않는다면) – harold

+0

또한 하나의 바이트가 있기 때문에'test all , al \ jp odd' – harold

+0

당신의 설명에서 얻은 바를 가지고 일부 코드를 바 꾸었습니다. 이전과 같은 문제와 출력이 나에게 여전히 주어졌습니다 ... – Ryan

답변

2

이것은 모든 스택 프레임 비즈니스를 없애고 (실제로는 필요하지 않으며 동적 스택 할당이 없음) 분기 처리 대신 setcc을 사용함으로써 상당히 단순화 될 수 있습니다 .

하면, 그 개수가 짝수인지 테스트 popcnt와 패리티 플래그를 사용

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 

타 간단한 방법 int32_t의 비트를 카운트 할 수 있지만, 단지 로우의 ​​패리티 검사 byte이므로 약간 줄이면됩니다.

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 
관련 문제