Search code examples
cassemblyx86bit-manipulationinline-assembly

Counting number of non-leading 0 in binary representation of given integer with a loop using add / jnc


I'm new to assemby language and I have a problem with:

int main(){
  int x = 2023; //nine 1 and two 0 as in bin it's - 11111100111
  int y;
  
  asm(
    "mov eax, %1 ;"
    "mov ecx, 32 ;"
    "mov ebx, 0 ;"
    "loop:"
      "add eax, eax ;"
      "jnc next ;"
      "inc ebx ;"
      "next :"
      "dec ecx ;"
      "jnz loop;"
    "mov %0, ebx ;"

    : "=r" (y)
    : "r"(x)
    : "eax", "ebx", "ecx"
  );

The code is compiled using -masm=intel.

I want this program to count number of 0 in binary representation of x. Right now it works on counting 1 in it but I can't figure it out what needs to be changed. I tried to change couple of functionalities but it either gives me wrong value or the value is the same.

And for clarification of given code. Right now result given by it is good because it counts 1 in 2023 but i want to reverse it somehow for it to count 0 not 1. I tried couple of methods by changing add, inc, dec etc. but somehow result was either 23 or 41 (idk how)


Solution

  • A solution that stays close to what you haved coded already. (Apparantly you follow a constraint about 'loop using add / jnc'.)

    • The L1 loop first locates the highest set bit in the EAX register
    • The L2 loop later tallies the embedded zero bits as requested
                         ; "mov eax, %1 ;"
        mov  ebx, 0
        mov  ecx, 32
    L1: add  eax, eax
        jc   L3          ; Found highest 1 bit
        dec  ecx
        jnz  L1
        jmp  L4          ; EAX was 0
    L2: add  eax, eax
        jc   L3
        inc  ebx         ; Count zeroes
    L3: dec  ecx
        jnz  L2
    L4:                  ; "mov %0, ebx ;"