CMPT 295 Unit - Machine-Level Programming
Lecture 10 – Assembly language basics: leaq instruction, memory addressing modes and arithmetic & logical operations
Last Lecture
- As x86-64 assembly s/w dev., we now get to see more of the microprocessor (CPU) state: PC, registers, condition codes
- x86-64 assembly language – Data
- 16 integer registers of 1, 2, 4 or 8 bytes + memory address of 8 bytes
- Floating point registers of 4 or 8 bytes
- No aggregate types such as arrays or structures
- x86-64 assembly language – Instructions
- mov* instruction family
- From register to register
- From memory to register
- From register to memory
- Memory addressing modes
- Cannot do memory-memory transfer with a single mov* instruction
- mov* instruction family
Why cannot do memory-memory transfer with a single mov* instruction?
- No x86-64 assembly instructions that take 2 memory addresses as operands
- Such instruction would
- Makes for very long machine instructions
- Require more complex decoder unit (on microprocessor) in other words, require more complex microprocessor datapath
- Memory only has one data bus and one address bus
- No appetite for instruction set architects to create such instructions
- Registers very fast and can easily be used for such transfer
- More info here: https://stackoverflow.com/questions/33794169/why-isnt-movl-frommemory-to-memory-allowed
Last Lecture
Requirement: When reading/writing assembly code…
- add a comment at the top of your function in your assembly code describing the parameter-toregister mapping
- Comment each of your assembly language instruction by explaining what it does using corresponding C statement or pseudocode
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
- Introduction
- C program -> assembly code -> machine level code
- Assembly language basics: data, move operation
- (highlighted) Memory addressing modes
- (highlighted) Operation leaq and Arithmetic & logical operations
- Conditional Statement – Condition Code + cmov*
- Loops
- Function call – Stack
- Array
- Buffer Overflow
- Floating-point operations
Various types of operands to x86-64 instructions
- Integer value as operand directly in an instruction
- This operand is called immediate
- Operand syntax: Imm
- Examples:
movq $0x4,%rax
andmovb $-17,%al
(NOTE: These instructions copy immediate value to register)
- Registers as operands in an instruction
(Note: So far, this is the type of operands what we have seen!)
- Operand value:
- Operand syntax: <- name of particular register
- Example:
movq %rax,%rdx
(NOTE: This instruction copies the value of one register into another register)
- 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
- 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))
- Indirect memory addressing mode
2. Indirect memory addressing mode
- When a register contains an address
- Similar to a pointer in C
- To access the data at the address contained in the register, we use parentheses (…)
- General Syntax: ()
- Effect: M[R[]]
2. Indirect memory addressing mode
Example: register to register
Assembly code: movq %rdx, %rax
Meaning, or affect: , or
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: or
Register | Before | After |
---|---|---|
%rax | 15 | 11 |
%rdx | 6 | 6 |
M[6] | 11 | 11 |
Other examples:
- register to memory:
movq %rax,(%rdx)
- immediate to memory:
movq $-147,(%rax)
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!
- Often used for address computations and general arithmetic computations
- Syntax:
leaq Source, Destination
- Example:
- Computing addresses
- if %rax <- 0x0000000000000008 and %rcx <- 16
leaq (%rax, %rcx), %rdx
- Once executed, rdx will contain 0x18
- Computing arithmetic expressions of the form where
- if %rdi <- variable a
leaq (%rdi, %rdi, 2), %rax
(%rdi is x, 2nd %rdi is y and 2 is k)- Once executed, rax will contain 3a
- C code:
return a*3;
- Computing addresses
- Operand Destination is a register
- Operand Source is a memory addressing mode expression
3. “Base + displacement” memory addressing mode
- General Syntax: Imm()
- Effect: M[Imm + R[]]
- Examples:
movq %rax, -8(%rsp)
leaq 7(%rdi), %rax
- Careful here!
- When dealing with
leaq
, the effect is Imm + R[] not M[Imm + R[]]
- When dealing with
4. Indexed memory addressing mode
- General Syntax: (,)
- Effect: M[R[] + R[]]
- Example:
movb (%rdi, %rcx), %al
- General Syntax: Imm(rb,ri)
- Effect: M[Imm + R[] + R[]]
- Example:
movw 0xA(%rdi, %rcx), %r11w
- Careful here! When dealing with
leaq
, the effect is
- R[] + R[] not M[R[] + R[]]
- Imm + R[] + R[] not M[Imm + R[] + R[]]
5. Scaled indexed memory addressing mode
- General Syntax: (,,s)
- Effect:
- Example:
(, %rdi, 2)
- General Syntax: Imm(,,s)
- Effect:
- Example:
3(, %rcx, 8)
- General Syntax:
- Effect:
- Example:
(%rdi, %rsi, 4)
- General Syntax:
- Effect:
- 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
- Absolute
- Indirect
- “Base + displacement”
- 2 indexed
- 4 scaled indexed
See Table of x86-64 Addressing Modes on Resources web page of our course web site
Box on left of slide:
- General Syntax:
- Effect:
Let’s try it!
Register | Value |
---|---|
%rdx | 0xf000 |
%rcx | 0x0100 |
Expression | Address Computation | Address |
8(%rdx) | 0xF000 + |
0xF008 |
(%rdx,%rcx) | 0xF100 |
|
(%rdx,%rcx,4) | 0xF400 |
|
0x80(,%rdx,2) | 0xE080 |
|
0x80(%rdx, 2) | invalid -> missing a “,” (comma) before %rdx |
|
0x80(,%rdx, 3) | invalid scalar value |
Two-Operand Arithmetic Instructions
* -> Size designator
- q -> long/64
- l -> int/32
- w -> short/16
- b -> char/8
Syntax | Meaning | Examples | in C |
add* Src, Dest |
addq %rax,%rcx |
x+=y |
|
sub* Src, Dest |
subq %rax,%rcx |
x-=y | |
imul* Src, Dest |
imulq $16,(%rax,%rdx,8) |
x*=y |
- “destination” and “first operand” are the same
- “2 operand” assembly language (machine)
mem = mem OP mem
usually not supported- 2 assembly code formats: ATT and Intel format (see Aside in Section 3.2 P. 177)
- We are using the ATT format
- Both order the operands of their instructions differently - Watch out!
Two-Operand Logical Instructions
- * -> Size designator
- q -> long/64
- l -> int/32
- w -> short/16
- b -> char/8
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 |
andl $252645135, %edi |
|
or* Src, Dest |
org %rsi,%rdi |
|
xor* Src, Dest |
xorq %rsi,%rdi |
- xorq special purpose:
xorq %rax, %rax
: zeroes register %raxmovq $0, %rax
: also zeroes register %rax
- x86-64 convention:
- Any instruction updating the lower 4 bytes will cause the higher-order bytes to be set to 0
xorl %eax, %eax
andmovl $0, %eax
<- also zeroes register%rax
Two-Operand Shift Instructions
- * -> Size designator
- q -> long/64
- l -> int/32
- w -> short/16
- b -> char/8
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
- * -> Size designator
- q -> long/64
- l -> int/32
- w -> short/16
- b -> char/8
Syntax | Meaning | Examples |
inc* Dest |
incq (%rsp) |
|
dec* Dest |
decq %rsi |
|
neg* Dest |
negl %eax |
|
not* Dest |
Dest = ~Dest | notq %rdi |
Summary
leaq
- load effective address instruction- Various types of operands to x86-64 instructions
- Immediate (constant integral value)
- Register (16 registers)
- Memory address (various memory addressing modes)
- General Syntax:
- Arithmetic & logical operations
- Arithmetic instructions:
add*
,sub*
,imul*
,inc*
,dec*
,neg*
,not*
- Logical instructions:
and*
,or*
,xor*
- Shift instructions:
sal*
,sar*
,shr*
- Arithmetic instructions:
Next lecture
- Introduction
- C program -> assembly code -> machine level code
- Assembly language basics: data, move operation
- Memory addressing modes
- Operation
leaq
and Arithmetic & logical operations - Conditional Statement – Condition Code + cmov*
- Loops
- Function call – Stack
- Array
- Buffer Overflow
- Floating-point operations