CMPT 295 Unit - Machine-Level Programming

Lecture 10 – Assembly language basics: leaq instruction, memory addressing modes and arithmetic & logical operations

Last Lecture

Why cannot do memory-memory transfer with a single mov* instruction?

Last Lecture

Requirement: When reading/writing assembly code…

swap:
  # xp -> %rdi, yp -> %rsi
  movq (%rdi), %rax # L1 = *xp
  movq (%rsi), %rdx # L2 = *yp
  movq %rdx, (%rdi) # *xp = L2
  movq %rax, (%rsi) # *yp = L1
  ret

Today’s Menu

Various types of operands to x86-64 instructions

  1. Integer value as operand directly in an instruction
    • This operand is called immediate
    • Operand syntax: Imm
    • Examples: movq $0x4,%rax and movb $-17,%al (NOTE: These instructions copy immediate value to register)
  2. Registers as operands in an instruction (Note: So far, this is the type of operands what we have seen!)
    • Operand value: R[ra]R[r_{a}]
    • Operand syntax: %ra\%r_{a} <- name of particular register
    • Example: movq %rax,%rdx (NOTE: This instruction copies the value of one register into another register)
  3. Memory address – using various memory addressing modes as operands in an instruction

Memory addressing modes

We access memory in an x86-64 instruction by expressing a memory address through various memory addressing modes

  1. Absolute memory addressing mode
    • Use memory address as operand directly in instruction
    • The operand is also called immediate * Operand syntax: Imm * Effect: M[Imm] * Example: call plus (NOTE: plus refers to the memory address of the first byte of the first instruction of the function called plus (see Demo))
  2. Indirect memory addressing mode

2. Indirect memory addressing mode

2. Indirect memory addressing mode

Example: register to register

Assembly code: movq %rdx, %rax

Meaning, or affect: raxrdx\text{rax} \leftarrow \text{rdx}, or R[rax]R[rdx]\text{R[rax]} \leftarrow \text{R[rdx]}

Register Before After
%rax 15 6
%rdx 6 6
M[6] 11 11

vs. memory to register

Assembly code: movq (%rdx),%rax

Meaning or affect: raxM[rdx]\text{rax} \leftarrow \text{M[rdx]} or R[rax]M[R[rdx]]\text{R[rax]} \leftarrow \text{M[R[rdx]]}

Register Before After
%rax 15 11
%rdx 6 6
M[6] 11 11

Other examples:

leaq - Load effective address instruction

leaq has the form of an instruction that reads from memory to a register (because of the parentheses), however it does not reference memory at all!

3. “Base + displacement” memory addressing mode

4. Indexed memory addressing mode

  1. General Syntax: (rbr_b,rir_i)
    • Effect: M[R[rbr_b] + R[rir_i]]
    • Example: movb (%rdi, %rcx), %al
  2. General Syntax: Imm(rb,ri)
    • Effect: M[Imm + R[rbr_b] + R[rir_i]]
    • Example: movw 0xA(%rdi, %rcx), %r11w
    • Careful here! When dealing with leaq, the effect is
  3. R[rbr_b] + R[rir_i] not M[R[rbr_b] + R[rir_i]]
  4. Imm + R[rbr_b] + R[rir_i] not M[Imm + R[rbr_b] + R[rir_i]]

5. Scaled indexed memory addressing mode

  1. General Syntax: (,rir_i,s)
    • Effect: M[R[ri]×s]M[R[r_i] \times s]
    • Example: (, %rdi, 2)
  2. General Syntax: Imm(,rir_i,s)
    • Effect: M[Imm+R[ri]×s]M[\text{Imm} + R[r_i] \times s]
    • Example: 3(, %rcx, 8)
  3. General Syntax: (rb,ri,s)(r_{b},r_{i},s)
    • Effect: M[R[rb]+R[ri]×s]M[R[r_b] + R[r_i] \times s]
    • Example: (%rdi, %rsi, 4)
  4. General Syntax: Imm(rb,ri,s)\text{Imm}(r_{b},r_{i},s)
    • Effect: M[Imm+R[rb]+R[ri]×s]M[\text{Imm} + R[r_b] + R[r_i] \times s]
    • Example: 8(%rdi, %rsi, 4) 13

Again, careful here! When dealing with leaq, the effect is not to reference memory at all!

Summary - Memory addressing modes

We access memory in an x86-64 instruction by expressing a memory address through various memory addressing modes

  1. Absolute
  2. Indirect
  3. “Base + displacement”
  4. 2 indexed
  5. 4 scaled indexed

See Table of x86-64 Addressing Modes on Resources web page of our course web site

Box on left of slide:

Let’s try it!

Register Value
%rdx 0xf000
%rcx 0x0100
Expression Address Computation Address
8(%rdx) 0xF000+(810=0x8)(8_{10} = \text{0x8}) 0xF008
(%rdx,%rcx) 0xF000=0x0100\text{0xF000} = \text{0x0100} 0xF100
(%rdx,%rcx,4) 0xF000+0x0100×4\text{0xF000} + \text{0x0100} \times 4 0xF400
0x80(,%rdx,2) 0x80+0xF000×2\text{0x80} + \text{0xF000} \times 2 0xE080
0x80(%rdx, 2) invalid -> missing a “,” (comma) before %rdx  
0x80(,%rdx, 3) invalid scalar value  

Two-Operand Arithmetic Instructions

* -> Size designator

Syntax Meaning Examples in C
add* Src, Dest Dest=Dest+Src\text{Dest} = \text{Dest} + \text{Src} addq %rax,%rcx x+=y
sub* Src, Dest Dest=DestSrc\text{Dest} = \text{Dest} - \text{Src} subq %rax,%rcx x-=y
imul* Src, Dest Dest=Dest×Src\text{Dest} = \text{Dest} \times \text{Src} imulq $16,(%rax,%rdx,8) x*=y

Two-Operand Logical Instructions

Transcriber’s note: the operators used for the logical operation in the following table are the proper mathematical symbols, not what is written in the document. The symbols used in the document are: &, | and ^ respectively.

Syntax Meaning Example
and* Src, Dest Dest=DestSrc\text{Dest} = \text{Dest} \land \text{Src} andl $252645135, %edi
or* Src, Dest Dest=DestSrc\text{Dest} = \text{Dest} \lor \text{Src} org %rsi,%rdi
xor* Src, Dest Dest=DestSrc\text{Dest} = \text{Dest} \oplus \text{Src} xorq %rsi,%rdi

Two-Operand Shift Instructions

Syntax Meaning Example Note
sal* Src, Dest Dest <- Dest « Src salq $4,%rax Left shift–also called shlq: filling Dest with 0, from the right
sar* Src, Dest Dest <- » Src sarl %cl,%rax Right arithmatic Shift: filling Dest with sign bit, form the left.
shr* Src, Dest Dest <- Dest » Src shrq $2,%r8 Right logical Shift: filling Rest with 0, from the left

One-Operand Arithmetic Instructions

Syntax Meaning Examples
inc* Dest Dest=Dest+1\text{Dest} = \text{Dest}+1 incq (%rsp)
dec* Dest Dest=Dest1\text{Dest} = \text{Dest}-1 decq %rsi
neg* Dest Dest=Dest\text{Dest} = -\text{Dest} negl %eax
not* Dest Dest = ~Dest notq %rdi

Summary

Next lecture