2017-04-07 37 views
0

我真的沒有的我在做什麼線索...... 的目標是增加了所有的1的,如果它甚至這樣說,如果它的奇這樣說 一個C/C++部分提供了傳遞到ASM在x86彙編加起來所有的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。它不輸出任何東西。 開頭和結尾都只是事情伊夫copped和運作良好,從而忽視那些其他工作粘貼,我知道他們可能是垃圾

這裏是我的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 

我應該怎麼做,我完全喪失並在可怕的... ...

+0

你不必比較所有偶數值,你可以使用'測試EBX,1 \ JZ even'。不要使用'loop'。這說'轉換爲binary'線使得在幾個方面沒有任何意義(它已經二進制和,如果不是該指令不會將它轉換) – harold

+0

此外,由於你似乎有一個單字節在那裏,你可以'測試人,人\ JP odd' – harold

+0

我改變了周圍的一些代碼我從你的解釋得到了BU它仍然像以前一樣給了我同樣的問題,並沒有輸出... – Ryan

回答

2

它可以被簡化很多,主要是通過擺脫所有的堆棧框架業務(這是真的沒有必要,沒有動態堆棧分配),並通過使用setcc而不是分支。

您可以popcnt算一個int32_t的位,然後測試數是偶數,

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 

的其他簡單的方法是使用奇偶標誌,但它只檢查低的奇偶字節所以要有點降低第一的,

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