Nukodi
Nukodi

Reputation: 357

Assembly language - what does sarq do in the code?

I am trying to translate assembly code back into C code but I noticed this one operation called sarq. I think q is for what size the address is but I do not know what the sarq does to the address. I commented on what I believe the code does.

.LC0    .string "ans %d\n" 
main:
.LFB0:                  val = -8(%rbp), result = -12(%rbp)
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movabsq $53162464113523643, %rax
        movq    %rax, -8(%rbp)      //val(variable) address -8,inputs value in %rax
        movl    $0, -12(%rbp)       //result(variable) address -12, inputs 0
        jmp     .L2         //starts loop
.L3:
        movq    -8(%rbp), %rax      //moves value in val into rax
        andl    $1, %eax        //dunno what eax is but adds 1 into it
        xorl    %eax, -12(%rbp)     //compares the value of eax and result to see if they are not equal. so compares 1 to 0
        sarq    -8(%rbp)        //does something to val?
.L2:
        cmpq    $0, -8(%rbp)        //compares val to 0
        jg      .L3         //if greater, goes to L3
        movl    -12(%rbp), %eax     //else, moves value from result into eax
        movl    %eax, %esi      //moves eax into esi
        movl    $.LC0, %edi     //Moves w/e $.LC0 is into edi. Based on the top, edi now holds that string?
        movl    $0, %eax        //moves 0 into eax
        call    printf          //print statement
        leave
        ret

Upvotes: 0

Views: 7940

Answers (2)

Ped7g
Ped7g

Reputation: 16606

andl $1, %eax //dunno what eax is but adds 1 into it

Uhmm... eax is lower 32b part of rax. And it's not add, but and. So from the quad value only the least significant bit (b0) will remain in eax.

That one is xor-ed with result value (initially zero).

And the quad value is shifted to right, by signed shift, but the constant is positive (0x00BCDEFABCDEFBBB), so doesn't matter. Otherwise that code would end in infinite loop, for negative constant! Human programmer would use shr in this case, so the function would work for any 64b value.

So the whole code calculates parity of that long constant (in quite ineffective way, plus it looks like unoptimized code), and then prints it as "ans #\n", where # is 0 (even count of set bits) or 1 (odd).

(I didn't debug it, just going after quick look on it, so maybe I missed something, you should try in debugger, what it really does).


BTW, good job with those comments, at least it was easy to point to you another problem. Without them nobody would notice, and only sarq would be answered.

Upvotes: 3

fuz
fuz

Reputation: 93082

sar is an arithmetic right shift. The single operand form shifts its operand right by one place, filling the topmost bit with the sign of the number. the suffix q indicates that the operand is a 64 bit operand (a quadword). Thus sarq -8(%rbp) shifts the quadword eight bytes below %rbp right by one place.

Upvotes: 2

Related Questions