# Assembly

Down to the very core of computers, every signal sent to any part of the machine is a series of electrical pulses. If the electrical pulse is high, for example 5 volts, that means a binary 1 digit is sent. If the electrical pulse is low, for example 0 volts, that means a binary 0 digit is sent. Put 4 binary digits together and you get a nibble. Put 8 together, you get a byte. Put 16 together, you get a word. Computers understand commands in such segments, but humans would rather not. So, they developed a better way of viewing such information and that was with hexadecimal. First of all, it didn't take 16 characters to show one command and in general, it became more convenient to remember commands like:

```90 - No Operation
CC - Break
E9 - 16 bit jump
CD - Interrupt
etc.
```

But soon, it was understood that such codes needed to be user friendly, so they invented assembly code. With assembly code, you can do any operation with special codes that made sense. For example, JMP jumped, INT interrupted, NOP did no operation, etc.

An assembler is the program that reads an assembly file (usually .asm) and converts it to a binary executable. This is very much akin to a compiler generating a executable program. However, assemblers are considered separately from compilers because compilers hide the low-level details of your system, while assemblers expose you to these details.

The source code written for any assembler is defined to be "Assembly language". But that doesn't mean much, since each assembler may require different source code for exactly the same program on an exactly identical platform.

## Assembly Syntax

In assembly, every instruction (or operation/operator/opcode) is followed by a comma-separated list of parameters (or operands). These operands can be either immediate values (i.e. numbers such as 1, 2, 0x16, 0101b), or registers, or a memory location. For example,

`mov eax, 123`

The instruction is mov, the operands are eax and 123. Here eax is a register and 123 is an immediate value.

There are two main different syntax for assembly: the Intel syntax, and the AT&T syntax.

### Intel Syntax

Generally speaking, the first operand of an operation is the destination operand, and the other operand (or operands) is the source operand. For example:

`mov eax, 123`

The mov instruction takes a value from the source operand, and places it in the destination operand, so the value 123 would be placed into the register eax. The original Intel syntax is that of the Intel ASM386 assembler (later licensed out to RadiSys but which eventually died off). Since then, many assemblers invented many variations of it. Also, it is used in most online assembly tutorials because the majority of those tutorials were written when TASM (which uses the Intel syntax) was the dominant assembler.

### AT&T Syntax

AT&T syntax is the reverse of Intel syntax. The data operated on moves from left to right. Here is the same statement as above in AT&T syntax.

`mov \$123, %eax`

There are also some other differences with operands:

• Literal values such as 123 are prefixed with '\$' (see example above).
• Memory locations have no prefix: mov 123, %eax. Moves the value stored at 123 to eax.
• Registers are prefixed with '%'
• When using a register as a pointer, it is put in parenthesis: mov (%eax), %ebx. Moves the value stored at the pointer stored in eax to ebx.
• When using a statement with memory locations (with no register present), a suffix is needed after the instruction. For example: movl \$123, 123. The 'l' (stands for long) is needed to tell the assembler that the values are 32 bits.
• Pointers can be offset by constants by prefixing them: 4(%eax) points to 4+%eax.
• Pointers can be offset by another register by writing them as: (%eax,%ebx) points to %eax+%ebx
• Finally you can combine it all and throw in a scale if you want: 4(%eax,%ebx,2) would be 4+%eax+%ebx*2