# ARM 64 Assembly Series — Data Processing (Part 2)

## Previous posts: Basic definitions and registers, lab setup, offset and addressing modes, Load And Store, Branch, Data Processing Part 1

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*

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:

*cs**el** Rd, Rn, Rm, cond ***means ***if cond then Rd = Rn else Rd = Rm*

*cs**inc** Rd, Rn, Rm, cond ***means ***if cond then Rd = Rn else Rd = Rm+1*

*cs**inv** Rd, Rn, Rm, cond ***means ***if cond then Rd = Rn else Rd = *˜*Rm*

*cs**neg** 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:

*c**inc** Rd, Rn, cond ***means ***if cond then Rd = Rn+1 else Rd = Rn*

*c**inv** Rd, Rn, cond ***means ***if cond then Rd = *˜*Rn else Rd = Rm+1*

*c**neg** 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:

*c**set**Rd, cond ***means ***if cond then Rd =1 else Rd=0*

*c**setm** 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 accordingelse

nzcv =#nzcvR_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 accordingelse

nzcv =#nzcvR_or_imm can be a register or an immediate

# Special instructions

C

ount leading zeros: clz Rn, Rmcounts the leading zero of Rm and stores the result to Rn:

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

Supervisor call:svc system_call_numberis 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:

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:

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.