KEMBAR78
x86 Assembly Language | PDF | Computer Science | X86 Architecture
0% found this document useful (0 votes)
17 views84 pages

x86 Assembly Language

The document provides an overview of x86 Assembly Language, detailing its architecture, features, and instruction set. It covers the evolution of the x86 ISA from the 8-bit 8080 microprocessor to modern 64-bit processors, as well as the segmented memory model and various addressing modes. Additionally, it introduces basic assembly instructions and their semantics, including data movement, arithmetic operations, and stack manipulation.

Uploaded by

Kunal Hazarika
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views84 pages

x86 Assembly Language

The document provides an overview of x86 Assembly Language, detailing its architecture, features, and instruction set. It covers the evolution of the x86 ISA from the 8-bit 8080 microprocessor to modern 64-bit processors, as well as the segmented memory model and various addressing modes. Additionally, it introduces basic assembly instructions and their semantics, including data movement, arithmetic operations, and stack manipulation.

Uploaded by

Kunal Hazarika
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 84

PowerPoint Slides

Basic Computer Architecture


Prof. Smruti Ranjan Sarangi
IIT Delhi

Chapter 5: x86 Assembly Language

1
2nd version

www.basiccomparch.com
Download the pdf of the book

videos

Slides, software, solution manual

Print version
The pdf version of the book and
(Publisher: WhiteFalcon, 2021)
all the learning resources can be
Available on e-commerce sites.
freely downloaded from the
website: www.basiccomparch.com
Overview of the x86 ISA
 It is not one ISA
 It is a family of ISAs
 The great-grandfather in the family
 Is the 8-bit 8080 microprocessor used in the mid-seventies
 The grandfather is the 16-bit 8086 microprocessor
released in 1978
 The parents are the 32 bit processors : 80386, 80486,
Pentium, and Pentium IV
 The current generation of processors are 64 bit
processors : Intel Core i3, i5, i7

3
Main Features of the x86 ISA

 It is a CISC ISA
 Has more than 300+ instructions
 Instructions can have a source/
destination memory operand
 Uses the stack for passing arguments, and
return addresses
 Uses segmented memory

4
Outline

 x86 Machine Model


 Simple Integer Instructions
 Branch Instructions
 Advanced Memory Instructions
 Floating Point Instructions
 Encoding the x86 ISA

5
View of Registers

 Modern Intel machines are still ISA compatible


with the arcane 16 bit 8086 processor
 In fact, due to market requirements, a 64 bit
processor needs to be ISA compatible with all
32 bit, and 16 bit ISAs
 What do we do with registers?
 Do we define a new set of registers for each
type of x86 ISA? ANSWER : NO

6
View of Registers – II
 Consider the 16 bit x86 ISA – It has 8 registers: ax, bx,
cx, dx, sp, bp, si, di

 Should we keep the old registers, and create a new


set of registers in a 32 bit processor?

 NO – Widen the 16 bit registers to 32 bits.

 If the processor is running a 16 bit program, then it


uses the lower 16 bits of every 32 bit register.

7
View of Registers – III
64 bits
32 bits
16 bits

rax eax ax
rbx ebx bx
rcx ecx cx
rdx edx dx 8 registers
rsp esp sp 64, 32, 16
bp
bit variants
rbp ebp
rsi esi si
rdi edi di
r8
The 64 bit ISA has
r9
8 extra registers
r8 - r15
r15
8
x86 can even Support 8 bit Registers

ax ah al

bx bh bl

cx ch cl

dx dh dl

 For the first four 16 bit registers


 The lower 8 bits are represented by : al, bl, cl, dl
 The upper 8 bits are represented by : ah, bh, ch, dh

9
x86 Flags Registers and PC

Fields in the flags register

64 bits
32 bits Field Condition Semantics
16 bits OF Overflow Set on an overflow
CF Carry flag Set on a carry or borrow
rflags eflags flags ZF Zero flag Set when the result is a 0,or the
comparison leads to an equality
rip eip ip
SF Sign flag Sign bit of the result

 Similar to the SimpleRisc flags register


 It has 16 bit, 32 bit, and 64 bit variants
 The PC is known as IP (instruction pointer)

10
Floating-point Registers

FP register
st0 st1 st0
st2 st0
st3 st4 st5 st6 st7
stack

 x86 has 8 (80 bit) floating-point registers


 st0 – st7
 They are also arranged as a stack
 st0 is the top of the stack
 We can perform both register operations, as well as
stack operations

11
View of Memory
 x86 follows a segmented memory model
 Each address in x86 is actually an offset from the start of the
segment.
 For example, an instruction address is an offset in the code
segment
 The starting address of the code segment is maintained in a
code segment (CS) register

CS Register Address

memory

Conceptual View
12
Segmentation in x86
16 bit segment registers

cs es
ss fs
ds gs

 x86 has 6 different segment registers


 Each register is 16 bits wide
 Code segment (cs), data segment (ds), stack segment
(ss), extra segment (es), extra segment 1 (fs), extra
segment 2 (gs)

13
Segmented vs Linear Memory Model
 In a linear memory model (e.g. SimpleRisc, ARM) the address
specified in the instruction is sent to the memory system
 There are no segment registers

 What are the advantages of a segmented memory model?


 The contents of the segment registers can be changed by the
operating system at runtime.
 Can map the text section(code) to another part of memory, or in
principle to other devices also (discussed in Chapter 10)
 Stores cannot modify the instructions in the text section.
REASON : Stores use the data segment, and instructions use the
code segment

14
How does Segmentation Work
 The segment registers nowadays contain an offset into a
segment descriptor table
 Because, 16 bits are not sufficient to store a memory
address
 Modern x86 processors have two kinds of segment
descriptor tables
 LDT (Local Descriptor Table), 1 per process, typically not used
nowadays
 GDT (Global Descriptor Table), contains 8191 entries
 Each entry in these tables contains the starting address of the
segment
15
Segment Descriptor Cache

 Every memory access needs to access the GDT or LDT :


VERY SLOW
 Use a segment descriptor cache (SDC) at each processor
that stores a copy of the relevant entries in the GDT
 Lookup the SDC first
 If an entry is not there, send a request to the GDT
 Quick, fast, and efficient

16
Memory Addressing Mode
𝑒𝑎𝑥
𝑐𝑠: 𝑒𝑎𝑥
𝑒𝑏𝑥
𝑑𝑠: 𝑒𝑏𝑥
𝑒𝑐𝑥 1
𝑠𝑠: 𝑒𝑐𝑥
𝑒𝑑𝑥
𝑎𝑑𝑑𝑟𝑒𝑠𝑠 = 𝑒𝑠: + 𝑒𝑑𝑥 ∗ 2 + 𝑑𝑖𝑠𝑝𝑙𝑎𝑐𝑒𝑚𝑒𝑛𝑡
𝑒𝑠𝑝 4
𝑓𝑠: 𝑒𝑏𝑝 𝑜𝑓𝑓𝑠𝑒𝑡
𝑒𝑏𝑝 ด8
𝑔𝑠: 𝑒𝑠𝑖
𝑒𝑠𝑖 𝑠𝑐𝑎𝑙𝑒
𝑒𝑑𝑖
𝑒𝑑𝑖 𝑖𝑛𝑑𝑒𝑥
𝑏𝑎𝑠𝑒

 x86 supports a base, a scaled index and an offset (known as the


displacement)
 Each of the fields is optional
17
Examples of Addressing Modes

Memory operand Value of the address Addressing mode


(in register transfer notation)
[eax] eax register-indirect
[eax + ecx*2] eax + 2 * ecx base-scaled-index
[eax + ecx*2 - 32] eax + 2* ecx - 32 base-scaled-index-offset
[edx - 12] edx - 12 base-offset
[edx*2] edx * 2 scaled-index
[0xFFE13342] 0xFFE13342 memory-direct

 x86 supports memory direct addressing


 The address can just be the index
 It can be a combination of the base, scaled index,
and displacement
18
Outline
 x86 Machine Model
 Simple Integer Instructions
 Branch Instructions
 Advanced Memory Instructions
 Floating Point Instructions
 Encoding the x86 ISA

19
Basic x86 Assembly
 We shall use the NASM assembler in this book
 Available at : http://www.nasm.us
 Generic structure of an assembly statement
 <label> : <assembly instruction> ; <comment>
 Comments are preceded by a ;
 x86 assembly instructions
 Typically in the 1 and 2 address format
 2 address format : <instruction> <operand 1> <operand 2>
 <operand 1> is typically both the source and destination

20
Basic x86 Assembly – II
 Rules for operands (for most instructions)
 Both the operands can be a register
 At most one of them can be an immediate
 At most one of them can be a memory location
 A memory operand is encapsulated in []
 Rules for immediates
 The size of an immediate is equal to the size of the
memory address
 For example, for a 32 bit machine, the maximum size of
an immediate is 32 bits
21
Basic x86 Assembly – III

 We shall use the 32 bit flavour of x86 in this book


 Readers can seamlessly write 16 bit x86 programs

 Simply use the registers : ax, bx, cx, dx, sp, bp, si, di

 Readers can also write 64 bit programs by using the registers :


rax, rbx, rcx, rdx, rsp, rbp, rsi, rdi, and r8 – r15

22
The mov instruction

Semantics Example Explanation


mov (reg/mem), (reg/mem/imm) mov eax, ebx eax ← ebx

 Extremely versatile instruction


 Can be used to load an immediate
 Load and store values to memory
 Move values between registers
 Example
 mov ebx, [esp – eax*4 - 12]

23
movsx and movzx instructions
Semantics Example Explanation
movsx reg, (reg/mem) movsx eax,bx eax ← sign extend(bx), the second
operand is either 8 or 16 bits
movzx reg, (reg/mem) movsx eax,bx eax ← zero extend(bx), the second
operand is either 8 or 16 bits

 The regular mov instruction assumes that the


source and destination have the same size
 The movsx and movzx instructions replace the MSB
bits by the sign bit, or zeros respectively

24
Exchange Instruction

Semantics Example Explanation


xchg (reg/mem), (reg/mem) xchg eax, [eax + edi] swap the contents of eax
and [eax + edi]

 Exchanges the contents of <operand 1> and


<operand 2>

25
Stack push and pop Instructions

Semantics Example Explanation


push (reg/mem/imm) push ecx temp ← ecx; esp ← esp - 4; [esp] ← temp
pop (reg/mem) pop ecx temp ← [esp]; esp ← esp + 4; ecx ← temp

 An x86 processor is aware of the stack


 It is aware that the stack pointer is stored in the
register, esp
 The push instruction decrements the stack pointer
 The pop instruction increments the stack pointer and
returns the contents at the top of the stack
26
Specifying Memory Operand Sizes

 The processor knows the size of a register operand


from its name
 eax is a 32 bit operand
 ax is a 16 bit operand
 What about memory operands ?
 push [eax] → How many bytes need to be pushed ?
 Solution : Use a modifier
 push dword [eax] ; pushes 32 bits
 Similarly, we need to use modifiers for other instructions such as
pop (when the number of bytes to be transferred are not known)

27
Modifiers
Modifier Size
byte 8 bits
word 16 bits
dword 32 bits
qword 64 bits

What is the value of ebx in this code snippet?

mov eax, 10
mov [esp], eax
push dword [esp]
mov ebx, [esp]

Answer: 10

28
ALU Instructions
Semantics Example Explanation
add (reg/mem), (reg/mem/imm) add eax, ebx eax ← eax + ebx
sub (reg/mem), (reg/mem/imm) sub eax, ebx eax ← eax - ebx
adc (reg/mem), (reg/mem/imm) adc eax, ebx eax ← eax + ebx + (carry bit)
sbb (reg/mem), (reg/mem/imm) sbb eax, ebx eax ← eax - ebx - (carry bit)

 All of these are 2 operand instructions


 The first operand is both the source and destination
 Example : Add registers eax, and ebx. Save the result in ecx
add eax, ebx
mov ecx, eax

29
Single Operand ALU Instructions

Semantics Example Explanation


inc (reg/mem) inc edx edx ← edx + 1
dec (reg/mem) dec edx edx ← edx - 1
neg (reg/mem) neg edx edx ← -1 * edx

Write an x86 assembly code snippet to compute: eax = -1 * (eax + 1).


Answer:

inc eax
neg eax

30
Compare Instruction

Semantics Example Explanation


cmp (reg/mem), (reg/mem/imm) cmp eax, [ebx+4] compare the values in eax, and
[ebx+4], and set the flags
cmp (reg/mem), (reg/mem/imm) cmp ecx, 10 compare the content of ecx with
10, and set the flags

 Similar to SimpleRisc, the cmp instruction


sets the flags

31
Multiplication and Division Instructions

Semantics Example Explanation


imul (reg/mem) imul ecx edx:eax ← eax * ecx
imul reg, (reg/mem) imul ecx, [eax + 4] ecx ← ecx * [eax + 4]
imul reg, (reg/mem), imm imul ecx, [eax + 4], 5 ecx ← [eax + 4] * 5
idiv (reg/mem) idiv ebx Divide (edx:eax) by the contents
of ebx; eax contains the quotient,
and edx contains the remainder.

 The imul instruction has three variants


 1 operand form → Saves the 64 bit result in edx:eax
 eax contains the lower 32 bits, and edx contains the
upper 32 bits

32
imul Instruction - II
Semantics Example Explanation
imul (reg/mem) imul ecx edx:eax ← eax * ecx
imul reg, (reg/mem) imul ecx, [eax + 4] ecx ← ecx * [eax + 4]
imul reg, (reg/mem), imm imul ecx, [eax + 4], 5 ecx ← [eax + 4] * 5
idiv (reg/mem) idiv ebx Divide (edx:eax) by the contents
of ebx; eax contains the quotient,
and edx contains the remainder.

 2 operand form
 The first operand (source and destination) has to be a
register
 The second operand can either be a register or
memory location

33
imul Instruction - III
Semantics Example Explanation
imul (reg/mem) imul ecx edx:eax ← eax * ecx
imul reg, (reg/mem) imul ecx, [eax + 4] ecx ← ecx * [eax + 4]
imul reg, (reg/mem), imm imul ecx, [eax + 4], 5 ecx ← [eax + 4] * 5
idiv (reg/mem) idiv ebx Divide (edx:eax) by the contents
of ebx; eax contains the quotient,
and edx contains the remainder.

 3 operand form
 First operand (destination) → register
 First source operand (register or memory)
 Second source operand (immediate)

34
idiv Instruction
Semantics Example Explanation
Divide (edx:eax) by the contents
idiv (reg/mem) idiv ebx
of ebx; eax contains the quotient,
and edx contains the remainder.

 Takes a single operand (register or memory)


 Dividend is contained in edx:eax
 edx contains the upper 32 bits
 eax contains the lower 32 bits
 The input operand contains the divisor
 eax contains the quotient
 edx contains the remainder
 While dividing by a negative number (set edx to -1 for sign
extension) 35
Example

Write an assembly code snippet to divide -50 by 3. Save the quotient in


eax, and remainder in edx.

Answer:

mov edx, -1
mov eax, -50
mov ebx, 3
idiv ebx

At the end eax contains -16, and edx contains -2.

36
Logical Instructions

Semantics Example Explanation


and (reg/mem), (reg/mem/imm) and eax, ebx eax ← eax AND ebx
or (reg/mem), (reg/mem/imm) or eax, ebx eax ← eax OR ebx
xor (reg/mem), (reg/mem/imm) xor eax, ebx eax ← eax XOR ebx
not (reg/mem) not eax eax ← ∼ eax

 and, or, and xor are standard 2 operand ALU


instructions where the first operand is also
the destination
 The not instruction is a 1 operand instruction

37
Shift Instructions
Semantics Example Explanation
sar (reg/mem), imm sar eax, 3 eax ← eax >> 3
shr (reg/mem), imm shr eax, 3 eax ← eax >>> 3
sal/shl (reg/mem), imm sal eax, 2 eax ← eax << 2

 sar (shift arithmetic right)


 shr (shift logical right)
 sal/shl (shift left)
 The second operand(shift amount) needs to be
an immediate
38
Example

What is the output of this code snippet?

mov eax, 0xdeadfeed


sar eax, 4

Answer: 0xfdeadfee

What is the output of this code snippet?

mov eax, 0xdeadfeed


shr eax, 4

Answer: 0xdeadfee

39
Outline

 x86 Machine Model


 Simple Integer Instructions
 Branch Instructions
 Advanced Memory Instructions
 Floating Point Instructions
 Encoding the x86 ISA

40
Simple Branch Instructions

Semantics Example Explanation


jmp < label > jmp .foo jump to .foo
j< condcode > j< condcode > .foo jump to .foo if the < condcode > condition
is satisfied

 jmp is a simple unconditional branch


instruction
 The conditional branches are of the form :
j<condcode> such as jeq, jne

41
Condition Codes in x86

Condition code Meaning


o Overflow
no No overflow
b Below (unsigned less than)
nb Not below (unsigned greater than or equal to)
e/z Equal or zero
ne/nz Not equal or not zero
be Below or equal (unsigned less than or equal)
s Sign bit is 1 (negative)
ns Sign bit is 0 (0 or positive)
l Less than (signed less than)
le Less than or equal (signed)
g Greater than (signed)
ge Greater than or equal (signed)

42
Example : Test if a number in eax is
prime. Put the result in eax
x86 assembly code
mov ebx, 2 ; starting index
mov ecx, eax ; ecx contains the original number
.loop:
mov edx, 0 ; required for correct division
idiv ebx
cmp edx, 0 ; compare the remainder
je .notprime ; number is composite
inc ebx
mov eax, ecx ; set the value of eax again
cmp ebx, eax ; compare the index and the number
jl .loop

; end of the loop


mov eax, 1 ; number is prime
jmp .exit ; exit
.notprime:
mov eax, 0
.exit:

43
Function Call and Return
Instructions
Semantics Example Explanation
call < label > call .foo Push the return address on the stack.
Jump to the label .foo.
ret ret Return to the address saved on the top
of the stack, and pop the entry

 The call instruction jumps to the <label>, and


pushes the return address on the stack
 Pops the stack top (assume it contains the return
address)

44
What does a typical function do ?

 Extracts the arguments from the stack


 Creates space on the stack to store the
activation block
 Spills some registers (if required)
 Calls other functions
 Does some processing
 Restores the stack pointer
 Returns
45
Example of a Recursive Function

Write a recursive function to compute the factorial of a number (≥ 1) stored in


eax. Save the result in ebx.
Answer:
x86 assembly code
factorial:
mov ebx, 1 ; default return value
cmp eax, 1 ; compare num (input) with 1
jz .return ; return if input is equal to 1

; recursive step
push eax ; save input on the stack
dec eax ; num--
call factorial ; recursive call
pop eax ; retrieve input
imul ebx, eax ; prod = prod * num

.return:
ret ; return

46
Implementing a Function
 Using push and pop instructions is fine for small
functions
 For large functions that have a lot of internal variables,
it might be necessary to push and pop a lot of values
from the stack
 For languages like C++ that dynamically declare local
variables, it might be difficult to keep track of the size
of the activation block.
 x86 processors thus save the starting value of esp in
the ebp register. At the end they set esp to ebp.

47
Recursive function for factorial :
without push/pop instructions
x86 assembly code
factorial:
mov eax, [esp+4]; get the value of eax from the stack

push ebp ; *** save ebp


mov ebp, esp ; *** save the stack pointer

mov ebx, 1 ; default return value


cmp eax, 1 ; compare num (input) with 1

jz .return ; return if input is equal

; recursive step
sub esp, 8 ; create space on the stack
mov [esp+4], eax ; save input on the stack
dec eax ; num--
mov [esp], eax ; push the argument
call factorial ; recursive call
mov eax, [esp+4] ; retrieve input
imul ebx, eax ; prod = prod * num

.return:
mov esp, ebp ; *** restore the stack pointer
pop ebp ; *** restore ebp
ret ; return
48
Enter and Leave Instructions
Semantics Example Explanation
enter imm, 0 enter 32, 0 push ebp (push the value of ebp on the
stack); mov ebp, esp (save the stack
pointer in ebp); esp ← esp - 32
leave leave mov esp, ebp (restore the value of esp);
pop ebp (restore the value of ebp)

 push ebp ; mov ebp, esp ; sub esp, <stack size> is a


standard sequence of operations
 The enter instruction does all the three operations
 mov esp, ebp ; pop ebp
 Standard sequence at the end of a function
 Both the operations are done by the leave instruction
49
Example with enter and leave
x86 assembly code
factorial:
mov eax, [esp+4] ; read the argument

enter 8, 0 ; *** save ebp and esp

mov ebx, 1 ; default return value


cmp eax, 1 ; compare num (input) with 1
jz .return ; return if input is equal to 1

; recursive step
mov [esp+4], eax ; save input on the stack
dec eax ; num--
mov [esp], eax ; push the argument
call factorial ; recursive call
mov eax, [esp+4] ; retrieve input
imul ebx, eax ; prod = prod * num

.return:
leave ; *** load esp and ebp
ret ; return

50
Outline

 x86 Machine Model


 Simple Integer Instructions
 Branch Instructions
 Advanced Memory Instructions
 Floating Point Instructions
 Encoding the x86 ISA

51
Advanced Memory Instructions
 These instructions are useful in moving a large
sequence of bytes from one location to another
 Also known as string instructions
 They make special use of the edi and esi
registers
 edi contains the default destination
 esi contains the default source

52
The lea instruction

 The lea (load effective address) inst. is


used to load an address in to the edi and
esi registers
 In general, lea can be used to load an address in to
any register
 lea ebx, [ecx + edx*2 + 16]
 ebx ← ecx + 2 * edx + 16

53
stosd instruction
 The stosd instruction does not have any
operands
 It saves the value in eax to [edi] (memory location in
edi)
 If the value of the DF flag in the flags register is 1
 edi ← edi – 4
 If the value in the DF flag in the flags register is 0
 edi ← edi + 4

 It is a post-indexed addressing mode


54
lodsd instruction
 The lodsd instruction does not have any
operands
 It saves the value in [esi] to eax (memory location in
esi)
 If the value of the DF flag in the flags register is 1
 esi ← esi – 4
 If the value in the DF flag in the flags register is 0
 esi ← esi + 4

 It is a post-indexed addressing mode


55
Summary of Memory Instructions
Semantics Example Explanation
lea reg, mem lea ebx, [esi + edi*2 + 10] ebx ← esi + edi*2 + 10
stos(b/w/d/q) stosd [edi] ← eax; edi ← edi + 4 * (−1)DF
lods(b/w/d/q) lodsd eax ← [esi]; esi ← esi + 4 * (−1)DF
movs(b/w/d/q) movsd [edi] ← [esi] ; esi ← esi + 4 * (−1)DF
edi ← edi + 4 * (−1)DF
std std DF ← 1
cld cld DF ← 0
DF → Direction Flag

 movsd : [edi] ← [esi]


 Auto increments esi, and edi based on the DF flag
 std : Sets the DF flag to 1
 cld : Sets the DF flag to 0
56
What is the value of eax after executing this code snippet?

mov dword [esp+4], 192


lea esi, [esp+4]
lea edi, [esp+8]
movsd
mov eax, [esp+8]

Answer: The movsd instruction transfer 4 bytes from the memory address
specified in esi to the memory address specified in edi. Since we write
192 to the memory address specified in esi, we shall read back the same
value in the last line.

57
Power of String Instructions

cld ; DF = 0
mov ebx, 0 ; initialisation of the loop index
.loop:
movsd ; [edi] <-- [esi]
inc ebx ; increment the index
cmp ebx, 10 ; loop condition
jne .loop

 Copy a 10 element array


 Starting address of source array in esi
 Starting address of destination array in edi

58
The rep prefix

Semantics Example Explanation


rep inst rep movsd val ← ecx; Execute the movsd instruction
val times; ecx ← 0

 Repeats a given instruction n times


 n is the value stored in ecx

cld ; DF = 0
mov ecx, 10 ; Set the count to 10
rep movsd ; Execute movsd 10 times

59
Outline

 x86 Machine Model


 Simple Integer Instructions
 Branch Instructions
 Advanced Memory Instructions
 Floating Point Instructions
 Encoding the x86 ISA

60
FP Machine Model

Constants
Integer FP
registers registers

Memory

 There is no direct connection between integer and


FP registers
 They can only communicate through memory
 No way to load floating-point immediates directly

61
FP Load Instructions
Semantics Example Explanation
fld mem fld dword [eax] Pushes an FP number stored in [eax] to
the FP stack
fld reg fld st1 Pushes the contents of st1 to the top of
the stack
fild mem fild dword [eax] Pushes an integer stored in [eax] to the
FP stack after converting it to a 32 bit
floating point number

 The fld instruction pushes the value of the first


operand (register/mem) to the FP stack
 The fild instruction pushes an integer stored in
memory to the FP stack
62
Assembler Directives
 There are two ways to load an FP immediate
 Store its hex representation to memory, and use the fld
instruction to bring the value to a FP register.
 Use an assembler directive to store the immediate as a
constant before the program starts. Then use the fld
instruction to transfer the value to the FP stack.
 In NASM :

section .data
num: dd 2.392

Declares a 32 bit floating-point constant : 2.392 in the data section

63
Assembler Directives – II

 Furthermore, the assembler associates the label


num with the memory address that saves 2.392
 In the assembly program, we need to write:
 fld dword [num]
 With this method, we do not have to save the
hex (binary) representation of a FP number. The
assembler will automatically do it for us.

64
FP Exchange

Semantics Example Explanation


fxch reg fxch st3 Exchange the contents of st0 and st3
fxch fxch Exchange the contents of st0 and st1

 Exchanges the contents of two floating point


registers

 st0 is always one of the FP registers

65
FP Store Instruction
Semantics Example Explanation
fst mem fst dword [eax] [eax] ← st0
fst reg fst st4 st4 ← st0
fstp mem fstp dword [eax] [eax] ← st0; pop the FP stack
fist mem fist dword [eax] [eax] ← int(st0)
fistp mem fistp dword [eax] [eax] ← int(st0); pop the FP stack

 The fst instruction saves the value of st0 to memory

 The fist instruction converts the FP value to an integer,


and than saves it in memory.

 With the 'p' suffix, the inst. also pops the FP stack

66
Example

A 32 bit floating point number is loaded in st0. Convert it to an integer and


save its value in eax.

Answer:

fist dword[esp+4] ; save st0 to [esp+4]


mov eax, [esp+4]

67
Variants of the FP add instruction
Semantics Example Explanation
fadd mem fadd dword [eax] st0 ← st0 + [eax]
fadd reg, reg fadd st0, st1 st0 ← st0 + st1 (one of the registers has
to be st0)
faddp reg, reg faddp st1, st0 st1 ← st0 + st1; pop the FP stack
fiadd mem fiadd dword [eax] st0 ← st0 + float([eax])

NASM fadd reg fadd st1 st0 ← st0 + st1


specific

 fadd adds two FP numbers


 faddp additionally pops the stack
 fiadd adds an integer in the first memory
operand to st0
68
Subtraction, Multiplication,
Division

Semantics Example Explanation


fsub mem fsub dword [eax] st0 ← st0 - [eax]
fmul mem fmul dword [eax] st0 ← st0 * [eax]
fdiv mem fdiv dword [eax] st0 ← st0 / [eax]

 fsub, fmul, fdiv have exactly the same


form (variants) as the fadd instruction

69
Example: Arithmetic Mean
Compute the arithmetic mean of two integers stored in eax and ebx. Save the
result (in 64 bits) in esp+4. Assume that the memory address, two, contains the
constant 2.

Answer:

; load the inputs to the FP stack


mov [esp], eax
mov [esp+4], ebx
fild dword [esp]
fild dword [esp+4]

fadd st0, st1 ; compute the sum


fdiv dword [two] ; arithmetic mean

fstp qword [esp+4] ; save the result to [esp+4]


; used the qword identifier
; for specifying 64 bits
70
Instructions for Special Functions

Semantics Example Explanation


fabs fabs st0 ← |st0|
fsqrt fsqrt st0 ← √st0
fcos fcos st0 ← cos(st0)
fsin fsin st0 ← sin(st0)

71
Example: Geometric Mean
Compute the geometric mean of two integers stored in eax and ebx. Save the
result (in 64 bits) in esp+4.

Answer:

; load the inputs to the FP stack


mov [esp], eax
mov [esp+4], ebx
fild dword [esp]
fild dword [esp+4]

fmul st0, st1 ; compute the product


fsqrt ; geometric mean

fstp qword [esp+4] ; save the result to [esp+4]


; used the qword identifier
; for specifying 64 bits

72
Compare Instructions
Semantics Example Explanation
fcomi reg, reg fcomi st0, st1 compare st0 and st1, and set the eflags
register (first register has to be st0)
fcomip reg, reg fcomi st0, st1 compare st0 and st1, and set the eflags
register; pop the FP stack

 The fcomi instruction compares the values


of two FP registers and sets the flags
 NOTE : It sets the flags for unsigned
comparison

73
Example
Compare sin(2θ) and 2sin(θ)cos(θ). Verify that they have the same value for any
given value of θ. Assume that θ is stored in the data section at the label theta, and
the threshold for floating point comparison is stored at label threshold. Save the
result in eax (1 if equal, and 0 if unequal).
Answer:

; compute sin(2*theta), and save in [esp]


fld dword [theta]
fadd st0, st0 ; st0 = theta + theta
fsin
fstp dword [esp] ; store the value

; compute (2*sin(theta)*cos(theta))
fld dword [theta]
fst st1 ; st1 = st0 = theta
fsin ; st0 = sin(theta)
fxch ; swap st0 and st1 (st1=sin(theta))
fcos ; st0 = cos(theta)
fmul st0, st1 ; st0 = sin(theta) * cos (theta)
fadd st0, st0 ; st0 = st0 + st0

74
Example – II
; compute the modulus of the difference
fld dword [esp] ; load (sin(2*theta))
fsub st0, st1 ; st0 = sin(2*theta)- 2*sin(theta)cos(theta)
fabs

; compare
fld dword [threshold]
fcomi st0, st1 ; compare
ja .equal ; threshold > difference (a for above)
mov eax, 0 ; else not equal
jmp .exit

.equal:
mov eax, 1 ; values are equal
.exit:

75
Stack Cleanup Instructions

Semantics Example Explanation


ffree reg ffree st4 Free st4
finit finit Reset the status of the FP unit including
the FP stack and registers

76
Outline
 x86 Machine Model
 Simple Integer Instructions
 Branch Instructions
 Advanced Memory Instructions
 Floating Point Instructions
 Encoding the x86 ISA

77
Overview of Instruction Encoding

Prefix Opcode ModR/M SIB Displacement Immediate


1-4 bytes 1-3 bytes 1 byte 1 byte 1/2/4 bytes 1/2/4 bytes
(optional) (optional) (optional) (optional) (optional)

 The 1-4 byte prefix specifies an optional


prefix
 Examples :
 Can be used to specify the rep prefix
 The lock prefix is used to specify that an instruction
executes atomically in a multiprocessor system

78
The ModR/M Byte
2 3 3

Mod Reg R/M

 Determines the addressing modes of the operands


 Mod bits : (addressing mode of one of the operands)
 00 → Register indirect addressing mode
 01 → Indirect addressing mode with 1 byte displacement
 10 → Indirect addressing mode with 4 byte displacement
 11 → Register direct addressing mode
79
The ModR/M Byte – II

 The Reg field specifies the register operand


(if necessary)

 The Mod and R/M bits determine the format


of the memory operand (if it exists)

 If R/M = 100 , we get the scale index and


base from the subsequent SIB byte

80
Scale Index Base
2 3 3

Scale Index Base

 There are four values of the scale : 00 (1), 01 (2), 10 (4),


11 (8)
 Both the index and base are 3 bits each, and follow the
register encoding scheme
 Some rules :
 esp cannot be an index
 The offset in the memory address can only be
specified in the displacement field
81
Register Encoding
Code Register
000 eax
001 ecx
010 edx
011 ebx
100 esp
101 ebp
110 esi
111 edi

** If the R/M bits are 100 , then we use the SIB byte
** If Mod = 00, and R/M = 101 (ebp), we use memory direct addressing
The 32 bit displacement is used as the memory address
82
Example
Encode the instruction: add ebx, [edx + ecx*2 + 32]. Assume that the opcode
for the add instruction is 0x03.

Answer:
Let us calculate the value of the ModR/M byte. In this case, our displacement
fits within 8 bits. Hence, we can set the Mod bits equal to 01 (corresponding to
an 8 bit displacement). We need to use the SIB byte because we have a scale
and an index. Thus, we set the R/M bits to 100. The destination register is ebx.
Its code is 011. Thus, the ModR/M byte is : 01 011 100 (0x5C)

Now, let us calculate the value of the SIB byte. The scale is equal to 2 (01). The
index is ecx(001), and the base is edx (010). Hence, the SIB byte is: 01 001 010
= 0x4A.

The last byte is the displacement, which is equal to 0x20.

Thus, the encoding of the instruction is : 03 5C 4A 20 (in hex)

83
THE END

84

You might also like