ARM 64 Assembly Series — Data Processing (Part 2)

In the first part of the data processing instruction set we talked about arithmetic, logical, move and shift operations. Continuing on the same track, in this part, we are going to discuss about multiplication and division, as well as the rest of the most important operations of the A64 instruction set including compare, conditional and special instructions.

Multiplication and Division

The mul, madd, msub and mneg can be used to multiply two 32bit or 64bit registers and get 32bit and 64bit results respectively:

When forming 64bit results from 32bit registers we have the following:

Replacing the s in the beginning of the mnemonic with a u denotes unsigned multiplication (umull, umaddl, umsubl, umnegl). For 128bit results the smulh and umulh can be used too calculate the upper 64bits and mull can be used for the rest, for example:

smulh Xd, Xm, Xn means Xd=Xm × Xm

Xd will hold the upper 64 bits of the result and the s denotes that the Xm and Xn must be sign extended. For the corresponding unsigned operation we have the following:

umulh Xd, Xm, Xn means Xd=Xm × Xm

When it comes to division we have the sdiv and udiv to divide and unsigned divide. For example:

sdiv Rd, Rm, Rn means Rd=Rm ÷ Rm

Comparison

The comparison operators are used to set the PSTATE flags and don’t have any further effect as the result is discarded. Their general syntax is as follows:

op Rn, operand2

https://comp.anu.edu.au/courses/comp2300/resources/ARM_cheat_sheet

For example the statement cmp X0, #0x40 will subtract 0x40 from X0 and if the result is negative, it will set the N flag of the PSTATE register. Similarly cmn will add the first and second operand in order to set the N flag accordingly. The TST instruction performs a bitwise AND operation on the value in Rn and the value of Operand2. This is the same as a ANDS instruction, except that the result is discarded.The TEQ instruction performs a bitwise Exclusive OR operation on the value in Rn and the value of Operand2. This is the same as a EORS instruction, except that the result is discarded.

Using compare, branch and and to construct loops is straightforward:

Conditional operations

This set of instructions is used to set the destination register equal to first or second operand, depending on certain conditions. Their syntax is as follows:

  • op Rd, Rn, Rm, <cond> (1)
  • op Rd, Rn, <cond> (2)
  • op Rd, <cond> (3)
  • op Rn, R_or_imm, nzcv, <cond> (4)

The <cond> can be one of the following:

  • In the first case (1) op can be either csel, csinc, csinv, csneg and can be interpreted as follows:

csel Rd, Rn, Rm, cond means if cond then Rd = Rn else Rd = Rm

csinc Rd, Rn, Rm, cond means if cond then Rd = Rn else Rd = Rm+1

csinv Rd, Rn, Rm, cond means if cond then Rd = Rn else Rd = ˜Rm

csneg Rd, Rn, Rm, cond means if cond then Rd = Rn else Rd = ˜Rm+1

  • In the second case (2) op can be either cinc, cinv or cneg and can be interpreted as follows:

cinc Rd, Rn, cond means if cond then Rd = Rn+1 else Rd = Rn

cinv Rd, Rn, cond means if cond then Rd = ˜Rn else Rd = Rm+1

cneg Rd, Rn, cond means if cond then Rd = ˜Rn else Rd = Rn

  • In the third case (3) op can be either cset or csetm and can be interpreted as follows:

cset Rd, cond means if cond then Rd =1 else Rd=0

csetm Rd, cond means if cond then Rd =0xffff..fff else Rd=0x0000..000

  • Finally in case (4) op can be either ccmp or ccmn and can be interpreted as follows:

The conditional compare ccmp Rn, R_or_imm, #nzcv, cond can be interpreted as follows:

if <cond> then
cmp Rn with R_or_imm and set the nzcv according
else
nzcv = #nzcv
R_or_imm can be a register or an immediate

As being said before, while cmp a, b executes a-b and sets the PSTATE flags accordingly, cmn on the other hand executes a+b, this affects the conditional compare as follows:

if <cond> then
cmn Rn with R_or_imm and set the nzcv according
else
nzcv = #nzcv
R_or_imm can be a register or an immediate

Special instructions

Count leading zeros: clz Rn, Rm counts the leading zero of Rm and stores the result to Rn:

Move Status to Register or register to status: mrs Rn, status or msr status, Rn:

Supervisor call: svc system_call_number is used to perform a system call. Depending on the operating system, each call has a specific id as it is depicted in the figure below:

full list here: https://chromium.googlesource.com/chromiumos/docs/+/master/constants/syscalls.md

The system_call_number in Linux is always set to 0 while the actual id is store in X8 and up to six parameters can be passed to x0-x5:

The system call id is stored in x8, x0-x2 stores the three arguments (“/bin/sh”,null,null) and svc 0 will perform the system call

No operation: nop which does nothing, other than advance the value of the program counter by 4. This instruction can be used for instruction alignment purposes.

--

--