Before we continue with command line parsing, we will have a brief diversion covering how arithmetic instructions work. We have already seen the increment and decrement instructions, `incq`

and `decq`

. These add one and subtract one from the value in a register. Now we will be covering more general arithmetic operations. In a previous post we saw how to use comparison instructions. Arithmetic instructions are really quite similar.

If we wish to add two quad-word values, we use the `addq`

instruction. The syntax is:

`addq X, Y`

where X is the name of a register or a constant value and Y is the name of a register. So the instruction `addq $17, %rax`

adds 17 to the value in register `rax`

and stores the result in `rax`

. To subtract we use the `subq`

instruction which uses the exact same syntax.

There are two different multiplication instructions. The first, `imulq`

, works just like the `addq`

and `subq`

instructions. This performs signed multiplication. However, as the result is stored in a single 64 bit register this instruction can quite easily lead to an overflow. Indeed, if we try to use constant values that are too large the assembly step will fail. For example the instruction

`imulq $0x8000000, %rax `

will cause an error when you try and assemble. This is, roughly, because max positive value you can store in 32 bits is 7FFFFFFF. However, you can still move this value into a register and multiply that way.

There is another multiply syntax that allows us to multiply 64 bit numbers without overflow. This syntax uses two instruction names, `mulq`

and `imulq`

, but it takes a single register value. The instruction `imulq`

performs signed multiplication and the instruction `mulq`

performs unsigned multiplication. These instructions multiply the value in the supplied register by whatever value is in the `rax`

register and stores the result across `rdx`

and `rax`

. The lower 64 bits are stored in `rax`

and the upper 64 bits in `rdx`

.

To perform division we use `idivq`

and `divq`

. As before, `idivq`

is signed division, and `divq`

is unsigned division. The division instructions take a single argument, the name of a register. With these instructions, the CPU takes the values in `rax`

and `rdx`

as a single value, `rax`

is the lower 64 bits and `rdx`

is the upper 64 bits. It divides this value by the value in the register supplied. The result of this division is then stored in `rax`

and the remainder is stored in `rdx`

.

There is also a unary negation operation `negq`

, that negates the value in a register.

Many of these instructions will overflow. And, unlike in some higher level languages, our program will continue to execute happily with whatever values the registers now contain. To avoid this behaviour we use a special instruction: `jo`

. This is the *jump on overflow* instruction. Whenever an arithmetic operation that causes an overflow occurs the CPU sets the overflow flag. The `jo`

instruction jumps conditioned on this flag. If the flag is set, execution jumps to the address supplied.

There are also versions of the above arithmetic operations for non-quad words. However we aren’t particularly interested in them right now.