Home > Net >  Does LSR affect C flag in arm64?
Does LSR affect C flag in arm64?

Time:09-08

I'm writing an arm64 assembly program to check if number is even or odd.

//**********************************
// Check if number is even or not  *
//**********************************
.global _start
_start: MOV     X5, #13          // Load the number
// Set up everything for print
    mov X0, #1                   // 1 = StdOut
    mov X8, #64                  // Linux write system call
// If number is divisible by two, C flag is clear
    LSR X6, X5, #1               // Divide by 2
    B.CS    odd                  // If NOT divisible by 2, jump to odd
even:   ldr X1, =evenD           // Load addr of even str
    mov     X2, #11              // Set up length of even str
    B   end                      // B to avoid odd case
odd:    ldr X1, =oddD            // Load addr of odd string
    mov X2, #12                  // Set up length of odd str
end:    svc 0                    // Tell Linux to print
    mov X0, #0                   // Ret code 0
    mov X8, #93                  // Code 93 to terminate
    svc 0                        // Tell linux to terminate
// Data section
.data
evenD:  .ascii  "It's even!\n"
oddD:   .ascii  "That's odd!\n"

Behaviour that I'd expect is that LSR will divide the number at X5 by 2 and if number is odd, then C flag will be set. If flag is set (number is odd) program branches to odd label.

The problem is that carry flag is not set. When I inspect cpsr register in gdb it doesn't change after LSR instruction. I've also tried to use LSRS as many data processing instructions without S don't affect carry flags, but that instruction doesn't exist:

as -g even.s -o even.o
even.s: Assembler messages:
even.s:10: Error: unknown mnemonic `lsrs' -- `lsrs X6,X5,#1'

As a result, no matter which number I use, according to my program they are all even. So the question is: why C flag in cpsr doesn't change when I shift out 1 from the register?

CodePudding user response:

Both lsr and lsl instructions are actually aliases of ubfm that doesn't affect the cpsr on aarch64

You are right. I don't like it either. Stupid IMO.

You should amend your code :

tst x5, #1
b.ne odd
  • Related