# Central Processing Unit (CPU)
## General Register Organization
### Addressing Modes
Addressing modes refer to the way that the microprocessor identifies the location of the operands of data from the instruction. It specifes a rule for interpreting or modifying the address field of the instruction before the operand is actually executed.
An ASM program consists of **opcode and operand.**
The **memory address of an operand** consists of two components:
- starting address
- effective address / offset
- combination of **displacement, base, index**
**Displacement:** 8 bit or 16 bit immediate value given in the instruction
**Base:** Contents of base register (BX or BP)
**Index:** Content of index register (SI or DI)
We have the following addressing modes:
- Register Direct addressing
- Immediate addressing
- Memory addressing
- Memory Direct addressing
- Register Indirect addressing
- Displacement addressing
- Indexed addressing
- Scaled addressing
### Register Direct Addressing
The operand to be accessed is specified as a register. Memory is not accessed, so it's faster. **Source and destination registers must match in size.** Here's an example:
```nasm
MOV BX, DX
MOV AL, CX ; not possible since sizes do not match
```


### Immediate Addressing
This mode refers to the address field of the instruction is the value itself. We're immediately placing constant data to the address. This requires no memory address and can only be used to specify a source operand.
Note that this addressing mode is possible for all registers **except for segment and flag registers.**
```nasm
MOV BX, 1234H
MOV AL, 35H
ADD AL, 40H
SUB BX, 15H
MOV DS, 1234H ; illegal (ask what to do)
```

### Memory Addressing
This involves addressing physical addresses through:
- Segment Base Address (SBA)
- identify starting location of segment in memory
- Effective Address (EA)
- offset of operand from the beginning of the segment in memory
**Memory Direct Addressing**
Involves the use of values as the offset address itself by enclosing it with square brackets:
```nasm
MOV DL, [2400] ; move contents from the address DS:2400H into DL
```
Note that this is the case of the offset within a segment which is `PA = Segment Base : Direct Address`. By using the Segment Override Prefix (SOP) in the instruction, we can reference any of the four segment registers.

**Memory Indirect Addressing**
It uses square brackets as well, but we don't enclose immediate values but rather those from the registers. **The machine has to obtain the value stored in the register to load the offset.** Instruction with this addressing mode indicates which register contains the needed data.
The address of the memory location where the operand resides is held by the register where **only BX, BP, SI, DI can be used:**
```nasm
MOV AL, [BX] ; moves DS:BX contents into AL
MOV CL, [SI] ; moves DS:SI contents into CL
MOV [DI], AH ; moves AH contents into address pointed by DS:DI
MOV [BP], AH ; moves AH contents into address pointed by SS:BP
```
This is the case of `PA = Segment Base : Indirect Address`.

**Displacement Addressing**
This involves adding a displacement in the address relative to the register:
```nasm
MOV CX [BX]+10 ; moves contents from the location of DS:BX + 10 into CX
MOV CX, [BX+10] ; same
MOV AL, [NUM1+20]
```
**Indexed Addressing**
```nasm
MOV CL, [BX][DI] ; PA = DS:BX+DI
```
**Scaled Addressing**
Note that scale can only be 1, 2, 4, or 8:
```nasm
MOV AX, 4*[BX]
MOV ECX, [EDI*4]
```
### Offset Registers For Various Segments
| Segment Register | CS | DS | ES | SS |
| - | - | - | - | - |
| Offset Register | IP | SI, DI, BX | SI, DI, BX | SP, BP |
Since DS and ES holds the same offset registers, we can override segments through:
```nasm
MOV AL, [BX] ; DS:BX by default
MOV AL, ES:[BX] ; overrides to ES:BX
MOV AX, [BP] ; SS:BP by default
MOV AX, DS:[BP] ; overrides to DS:BP
```
## Exercises
### Question 1
Assume the registers BX, SI, and DI contain the following value:
**BX= 0200H, SI = 8124H, DI =FF78H,DS=0000H**
The memory locations contain the following values:
- **mem(1200H) = 82ABH**
- **mem(0200H) = 3CD6H**
- **mem(8324H) = 1AB4H**
and the label **ALPHA has the value 1200H with the address 1000H.**
For each of the following instructions (executed separately), **specify the addressing mode used, write the expression for effective address, calculate it, and give the result of operation.**
```nasm
ADD BX, 1234H
ADD SI, [BX]
SUB DI, [BX][SI]
MOV ALPHA, BX
MOV AX, [BX]ALPHA
```
### Answers
```nasm
ADD BX, 1234H
```
- immediate addressing
- EA: none
- BX: 0200H + 1234H = 1434H
```nasm
ADD SI, [BX]
```
- memory indirect addresssing
- EA: 0200H
- SI: 8124H + 3CD6H = BDFAH
```nasm
SUB DI, [BX][SI]
```
- indexed addressing
- EA: 0200H + 8124H = 8324H
- DI = FF78H - 1AB4H = E4C4H
```nasm
MOV ALPHA, BX
```
- register direct addressing,
- EA: none
- ALPHA: 0200H **(flags no affected)**
```nasm
MOV AX, [BX]ALPHA
```
- indexed addressing
- EA: 0200H + **1000H (not the value)** = 1200H
- AX: 82ABH (flags not affected)
Question 2
Tell if the following instructions (The instructions are independent.) based on the Intel 8086 CPU are true or false, and correct the wrong one without modifying the instruction mnemonic.
```nasm
ADD 0034H,4800H
ADD [0034H], SS:4800H
ADD BL,4800H
ADD [AX],4800H
ADD [4800H], BL
ADD [4800H], BX
ADD BX, [AX+4800H]
ADD BX, [SI+DI]
ADD BX, [SI+DI+4800H]
ADD ECX, [ EBX + EDI*10 ]
```
### Answers
`ADD 0034H, 4800H`
- false, **requires at least one operand to be memory address or register, immediate values can only be on source operand as well**
- `ADD [0034H], 4800H` to enclose value as an address in destination operand
`ADD [3400H], SS:4800H`
- false, **segment overrides cannot be applied on immediate values,** only available for memory operands
- `ADD ES:[3400H], 4800H` assumes valid segment override prefix at the memory location on destination operand
`ADD BL, 4800H`
- false, **size doesn't match,** BL is an 8-bit register, cannot hold 16-bit values
- `ADD BX, 4800H` to change to 16-bit register BX
`ADD [AX], 4800H`
- false, **square brackets only apply on BX, BP, SI, and DI**
- `ADD [BX], 4800H` changes to BX
`ADD [4800H], BL`
- true
`ADD [4800H], BX`
- true, but a better practice will be to define a size like `WORD PTR`
`ADD BX, [AX+4800H]`
- false, square brackets doesn't apply on AX
- `ADD BX, [SI+4800H` for the correct displacement addressing
`ADD BX, [SI+DI]`
- false, invalid addressing mode, **supports** `[BP+SI]` **and** `[BP+DI]` **instead**
- `ADD BX, [BP+SI]`
`ADD BX, [SI+DI+4800H]`
- false, **8086 does not support this level of complexity in addressing**
- `ADD BX, [BX+SI+4800H]` with base and index
`ADD ECX, [EBX + EDI*10]`
- false, **scaled addressing only supports scales of 1, 2, 4, and 8**
- `ADD ECX, [EBX + EDI*2]` changes the scale to 2
All Answers summarized:
**False**
```nasm
ADD 0034H, 4800H -> ADD [0034H], 4800H
ADD [0034H], SS:4800H -> ADD ES:[0034H], 4800H
ADD BL, 4800H -> ADD BX, 4800H
ADD [AX], 4800H -> ADD [BX], 4800H
ADD BX, [AX+4800H] -> ADD BX, [SI+4800H]
ADD BX, [SI+DI] -> ADD BX, [BP+SI]
ADD BX [SI+DI+4800H] -> ADD BX, [BX+SI+4800H]
ADD ECX, [EBX + EDI*10] -> ADD ECX, [EBX + EDI*2]
```
**True**
```nasm
ADD [4800H], BL
ADD [4800H], BX
```
### Question 3
Plot the corresponding memory map for the given data segment (Based on Intel 8086 CPU).
```nasm
DATA SEGMENT
ABC DB 30, 34H
DEF DW 12, 56ABH, 'A'
HIJ DB 3 DUP(-1)
DATA ENDS
```
### Answers
`ABC DB 30 34H`:
- `DB`: byte-sized data
- 30 = 1EH
```
Label Address Content
ABC DS:0000 1EH
ABC+1 DS:0001 34H
```
`DEF DW 12, 56ABH, 'A'`
- `DW`: word-sized data (2 bytes per word)
- 12D = 0CH is stored as 000CH, 12 is at the lower endian (bit 0 - bit 7)
- we store 0CH first then 00H
- simiarly, 56H then ABH
- 'A' = 65D = 41H
- 'A' is 0041H, 41H then 00H
```
Label Address Content
ABC DS:0000 1EH
ABC+1 DS:0001 34H
DEF DS:0002 0CH
DEF+1 DS:0003 00H
DEF+2 DS:0004 56H
DEF+3 DS:0005 ABH
DEF+4 DS:0006 41H
DEF+5 DS:0007 00H
```
`HIJ DB 3 DUP(-1)`
- `DUP`: repeats multiple times
- `3 DUP(-1)`: repeats 3x -1 (FFH)
```
Label Address Content
ABC DS:0000 1EH
ABC+1 DS:0001 34H
DEF DS:0002 0CH
DEF+1 DS:0003 00H
DEF+2 DS:0004 56H
DEF+3 DS:0005 ABH
DEF+4 DS:0006 41H
DEF+5 DS:0007 00H
HIJ DS:0008 FFH
HIJ+1 DS:0009 FFH
HIJ+2 DS:000A FFH <- remember that we're dealing with hex
```
We have completed the memory map for the given data segment.