COMPUTER ORGANIZATION
AND ASSEMBLY LANGUAGE
LECTURE-5-MACHINE LEVEL PROGRAMMING-II
MUHAMMAD HAFEEZ
DEPARTMENT OF COMPUTER SCIENCE
GC UNIVERSITY LAHORE
Data Formats
 Due to its origins as a 16-bit architecture
that expanded into a 32-bit one, Intel
uses the term “word” to refer to a 16-bit
data type.
 Based on this, they refer to 32-bit
quantities as “double words.”
 They refer to 64-bit quantities as “quad
words.”
 Most instructions we will encounter
operate on bytes or double words.
Data Formats
 Most of the common data types are
stored as double words. This includes
both regular and long int’s, whether or
not they are signed.
 All pointers (such as char *) are stored
as 4-byte double words. Bytes are
commonly used when manipulating string
data.
Data Formats
 More recent extensions of the C language
include the data type long long, which is
represented using 8 bytes.
 However, IA32 does not support this data
type in hardware. But, the compiler must
generate sequences of instructions that
operate on these data 32 bits at a time
Data Formats
 More recent extensions of the C language
include the data type long long, which is
represented using 8 bytes.
 However, IA32 does not support this data
type in hardware. But, the compiler must
generate sequences of instructions that
operate on these data 32 bits at a time
Data Formats
 More recent extensions of the C language
include the data type long long, which is
represented using 8 bytes.
 However, IA32 does not support this data
type in hardware. But, the compiler must
generate sequences of instructions that
operate on these data 32 bits at a time
Data Formats
 Floating-point numbers come in three different
forms: single-precision (4-byte) values,
corresponding to C data type float
 Double-precision (8-byte) values, corresponding
to C data type double;
 Extended-precision (10-byte) values .
 Gcc uses the data type long double to refer to
extended-precision floating-point values. It also
stores them as 12-byte quantities to improve
memory system performance, as will be discussed
later. Using the long double data type (introduced
in ISO C99) gives us access to the extended-
precision capability of x86.
Data Formats
 Floating-point numbers come in three different
forms: single-precision (4-byte) values,
corresponding to C data type float
 Double-precision (8-byte) values, corresponding
to C data type double;
 Extended-precision (10-byte) values .
 Gcc uses the data type long double to refer to
extended-precision floating-point values. It also
stores them as 12-byte quantities to improve
memory system performance, as will be discussed
later. Using the long double data type (introduced
in ISO C99) gives us access to the extended-
precision capability of x86.
Data Formats
 Most assembly code instructions generated by gcc
have a single-character suffix denoting the size of
the operand.
 For example, the data movement instruction has
three variants: movb (move byte), movw (move
word), and movl (move double word).
 The suffix ‘l’ is used for double words, since 32-bit
quantities are considered to be “long words,” a
holdover from an era when 16-bit word sizes were
standard.
Data Formats
Accessing Information
 An IA32 central processing unit (CPU) contains
a set of eight registers storing 32-bit values.
 These registers are used to store integer data
as well as pointers.
 Their names all begin with %e, but otherwise,
they have peculiar names.
 With the original 8086, the registers were 16
bits and each had a specific purpose. The
names were chosen to reflect these different
purposes. With flat addressing, the need for
specialized registers is greatly reduced.
Accessing Information
 For the most part, the first six registers can be
considered general-purpose registers with no
restrictions placed on them.
 We said “for the most part,” because some
instructions use fixed registers as sources
and/or destinations.
 In addition, within procedures there are
different conventions for saving and restoring
the first three registers (%eax, %ecx, and
%edx) than for the next three (%ebx, %edi,
and %esi). (detail will be discussed in
procedures)
Accessing Information
 The final two registers (%ebp and %esp)
contain pointers to important places in the
program stack. They should only be altered
according to the set of standard conventions for
stack management.
 The low-order 2 bytes of the first four registers
can be independently read or written by the
byte operation instructions.
Accessing Information
 This feature was provided in the 8086 to allow
backward compatibility to the 8008 and 8080—
two 8-bit microprocessors that date back to
1974.
 When a byte instruction updates one of these
single-byte “register elements,” the remaining 3
bytes of the register do not change.
 Similarly, the low-order 16 bits of each register
can be read or written by word operation
instructions. This feature stems from IA32’s
evolutionary heritage as a 16-bit microprocessor
and is also used when operating on integers
with size designator short.
Some History: IA32 Registers
%eax
%ecx
%edx
%ebx
%esi
%edi
%esp
%ebp
%ax
%cx
%dx
%bx
%si
%di
%sp
%bp
%ah
%ch
%dh
%bh
%al
%cl
%dl
%bl
16-bit virtual registers
(backwards compatibility)
general
purpose
accumulate
counter
data
base
source
index
destination
index
stack
pointer
base
pointer
Origin
(mostly obsolete)
%rsp
x86-64 Integer Registers
 Can reference low-order 4 bytes (also low-order 1 & 2
bytes)
%eax
%ebx
%ecx
%edx
%esi
%edi
%esp
%ebp
%r8d
%r9d
%r10d
%r11d
%r12d
%r13d
%r14d
%r15d
%r8
%r9
%r10
%r11
%r12
%r13
%r14
%r15
%rax
%rbx
%rcx
%rdx
%rsi
%rdi
%rbp
Operand Specifiers
 Most instructions have one or more operands.
 specifying the source values and destination
values performing an operation and the
destination location into which to place the
result .
 IA32 supports a number of operand forms.
 Source values can be given as constants or read
from registers or memory.
 Results can be stored in either registers or
memory.
Operand Specifiers
 The different operand possibilities can be
classified into three types.
 The first type, immediate, is for constant
values.
 In ATT-format assembly code, these are written
with a ‘$’ followed by an integer using standard
C notation, for example, $-577 or $0x1F.
 Any value that fits into a 32-bit word can be
used, although the assembler will use 1- or 2-
byte encodings whenever possible.
Operand Specifiers
 The second type, register, denotes the contents
of one of the registers, either one of the eight
32-bit registers (e.g., %eax) for a double-word
operation, one of the eight 16-bit registers
(e.g., %ax) for a word operation, or one of the
eight single-byte register elements (e.g., %al)
for a byte operation.
Operand Specifiers
 There are many different addressing modes
allowing different forms of memory references.
The most general form is Imm(E b ,E i ,s)
 Such a reference has four components:
 An immediate offset Imm, a base register E b ,
an index register E i , and a scale factor s.
 The s must be 1, 2, 4, or 8.
 The effective address is then computed as Imm
+ R[E b ]+ R[E i ] . s.
 This general form is often seen when
referencing elements of arrays.
Operand Specifiers

Data Movement Instructions
 Among the most heavily used
instructions are those that copy data
from one location to another.
 The generality of the operand notation
allows a simple data movement
instruction to perform what in many
machines would require a number of
instructions.
Data Movement Instructions
 We group the many different instructions
into instruction classes, where the
instructions in a class perform the same
operation, but with different operand
sizes.
 For example, the mov class consists of
three instructions: movb, movw, and
movl. All three of these instructions
perform the same operation; they differ
only in that they operate on data of size
1, 2, and 4 bytes, respectively.
Data Movement Instructions
 The instructions in the mov class copy
their source values to their destinations.
 The source operand designates a value
that is immediate, stored in a register, or
stored in memory.
 The destination operand designates a
location that is either a register or a
memory address.
 IA32 imposes the restriction that a move
instruction cannot have both operands
refer to memory locations.
Data Movement Instructions
 Copying a value from one memory
location to another requires two
instructions—the first to load the source
value into a register, and the second to
write this register value to the
destination.
Data Movement Instructions
 The register operands for these
instructions can be any of the eight 32-
bit registers (%eax–%ebp) for movl, any
of the eight 16-bit registers (%ax–%bp)
for movw, and any of the single-byte
register elements (%ah–%bh,%al–%bl)
for movb.
Data Movement Instructions
 The following mov instruction examples
show the five possible combinations of
source and destination types.
 Recall that the source operand comes
first and the destination second:
Data Movement Instructions
 The following mov instruction examples
show the five possible combinations of
source and destination types.
 Recall that the source operand comes
first and the destination second:
Data Movement Instructions
 Both the movs and the movz instruction
classes serve to copy a smaller amount
of source data to a larger data location,
filling in the upper bits by either sign
expansion (movs) or by zero expansion
(movz).
 With sign expansion, the upper bits of
the destination are filled in with copies of
the most significant bit of the source
value. With zero expansion, the upper
bits are filled with zeros.
Data Movement Instructions
Difference between movb and movsbl and
movzbl?
Data Movement Instructions
Data Movement Instructions
Data Movement Instructions
 The final two data movement operations
are used to push data onto and pop data
from the program stack.
 The stack plays a vital role in the
 handling of procedure calls.
 We add data to a stack via a push
operation and remove it via a pop
operation, with the property that the
value popped will always be the value
that was most recently pushed and is still
on the stack.
Data Movement Instructions
 With IA32, the program stack is stored in
some region of memory.
 The stack grows downward such that the
top element of the stack has the lowest
address of all stack elements. (By
convention, we draw stacks upside down,
with the stack “top” shown at the bottom
of the figure). The stack pointer %esp
holds the address of the top stack
element.
Illustrations of Stack
Operations
Data Movement Instructions
 The pushl instruction provides the ability
to push data onto the stack, while the
popl instruction pops it. Each of these
instructions takes a single operand—the
data source for pushing and the data
destination for popping.
Data Movement Instructions
 Pushing a double-word value onto the
stack involves first decrementing the
stack pointer by 4 and then writing the
value at the new top of stack address.
 Therefore, the behavior of the instruction
pushl %ebp is equivalent to that of the
pair of instructions
 subl $4,%esp ;Decrement stack pointer
 movl %ebp,(%esp) ;Store %ebp on stack
 Except that the pushl instruction is encoded in the machine
code as a single byte, whereas the pair of instructions
shown above requires a total of 6 bytes.
Data Movement Instructions
 Popping a double word involves reading
from the top of stack location and then
incrementing the stack pointer by 4.
 Therefore, the instruction popl %eax is
equivalent to the following pair of
instructions:
 movl (%esp),%eax Read %eax from stack
 addl $4,%esp Increment stack pointer
Data Movement Instructions
 Since the stack is contained in the same
memory as the program code and other
forms of program data, programs can
access arbitrary positions within the stack
using the standard memory addressing
methods.
 For example, assuming the top most
element of the stack is a doubleword, the
instruction movl 4(%esp),%edx will copy
the second double word from the stack to
register %edx.
Data Movement Example
Data Movement Example
 The details are omitted of the assembly
code that allocates space on the run-time
stack on procedure entry and deallocates
it prior to return.The details of this set-up
and completion code will be covered
when we discuss procedure linkage. The
code we are left with is called the “body.”
Data Movement Example
 When the body of the procedure starts
execution, procedure parameters xp and
y are stored at offsets 8 and 12 relative
to the address in register %ebp.
 Instructions 1 and 2 read parameter xp
from memory and store it in register
%edx.
Data Movement Example
 Instruction 2 uses register %edx and reads x into
register %eax, a direct implementation of the
operation x = *xp in the C program.
 Later, register %eax will be used to return a value
from this function, and so the return value will be
x.
 Instruction 3 loads parameter y into register
%ecx. Instruction 4 then writes this value to the
memory location designated by xp in register
%edx, a directimplementation of the operation
*xp = y.
Data Movement Example
 Two features about this assembly code are worth
noting.
 First,we see that what we call “pointers” in C are
simply addresses. Dereferencing a pointer
involves copying that pointer into a register, and
then using this register in a memory reference.
 Second, local variables such as x are often kept
in registers rather than stored in memory
locations. Register access is much faster than
memory access.
Practice Problem
 Assume variables v and p declared with types
 src_t v;
 dest_t *p;
 where src_t and dest_t are data types declared with typedef. We
wish to use
 the appropriate data movement instruction to implement the
operation
 *p = (dest_t) v;
 where v is stored in the appropriately named portion of register
%eax (i.e., %eax,
 %ax, or %al), while pointer p is stored in register %edx.
 For the following combinations of src_t and dest_t, write a line of
assembly
 code that does the appropriate transfer. Recall that when
performing a cast that
 involves both a size change and a change of “signedness” in C, the
operation
 should change the signedness first
Practice Problem
Arithmetic and Logical Instructions
Arithmetic and Logical
Instructions
 Most of the operations are given as
instruction classes, as they can have
different variants with different operand
sizes.
 (Only leal has no other size variants.)
 For example, the instruction class add
consists of three addition instructions:
addb, addw, and addl, adding bytes,
words, and double words, respectively.
Arithmetic and Logical
Instructions
 Indeed, each of the instruction classes
shown has instructions for operating on
byte, word, and double-word data.
 The operations are divided into four
groups: load effective address, unary,
binary, and shifts. Binary operations have
two operands, while unary operations
have one operand.
Arithmetic and Logical
Instructions
 Load Effective Address:
 The load effective address instruction leal
is actually a variant of the movl
instruction. It has the form of an
instruction that reads from memory to a
register, but it does not reference memory
at all.
 Its first operand appears to be a memory
reference, but instead of reading from the
designated location, the instruction copies
the effective address to the destination.
Arithmetic and Logical
Instructions
 Load Effective Address:
 This instruction can be used to generate
pointers for later memory references.
Arithmetic and Logical
Instructions
 Load Effective Address:
 Another Use (Arithmetic):
 leal instruction can be used to compactly
describe common arithmetic operations.
 For example, if register %edx contains
value x, then the instruction
 leal 7(%edx,%edx,4), %eax
 will set register %eax to 5x + 7.
Arithmetic and Logical
Instructions
 Unary and Binary Operations:
 Operations in the second group are unary
operations, with the single operand serving
as both source and destination. This
operand can be either a register or a
memory location. For example, the
instruction incl (%esp) causes the 4-byte
element on the top of the stack to be
incremented. This syntax is equivalent to C
increment (++) and decrement (--)
operators.
Arithmetic and Logical
Instructions
 Unary and Binary Operations:
 The third group consists of binary
operations, where the second operand is
used as both a source and a destination.
This syntax is reminiscent of the C
assignment operators, such as x += y.
 Observe, however, that the source operand
is given first and the destination second.
Arithmetic and Logical
Instructions
 Unary and Binary Operations:
 For example, the instruction subl
%eax,%edx decrements register %edx by
the value in %eax. (It helps to read the
instruction as “Subtract %eax from%edx.”)
 The first operand can be either an
immediate value, a register, or a memory
location. The second can be either a
register or a memory location.
Practice Problem
Practice Problem
Arithmetic and Logical
Instructions
 Shift Instructions:
 In shift instructions, the shift amount is given
first, and the value to shift is given second.
 Both arithmetic and logical right shifts are
possible.
 The shift amount is encoded as a single byte,
since only shift amounts between 0 and 31 are
possible (only the low-order 5 bits of the shift
amount are considered). The shift amount is
given either as an immediate or in the single byte
register element %cl. (These instructions are
unusual in only allowing this specific register as
operand.)
Arithmetic and Logical
Instructions
 Shift Instructions:
 There are two instructions for left shift : sal and
shl. Both have the same effect, filling from the
right with zeros.
 The right shift instructions differ in that sar
performs an arithmetic shift (fill with copies of the
sign bit), whereas shr performs a logical shift (fill
with zeros).
 The destination operand of a shift operation can
be either a register or a memory location. We
denote the two different right shift operations as
>> A (arithmetic) and >> L (logical).
Discussion
 Most of the instructions can be used for
either unsigned or two’s complement
arithmetic. Only right shifting requires
instructions that differentiate between
signed versus unsigned data. This is one
of the features that makes two’s-
complement arithmetic the preferred way
to implement signed integer arithmetic.
Discussion
Discussion
 Function arguments x, y, and z are stored
in memory at offsets 8, 12, and 16
relative to the address in register %ebp,
respectively.
Discussion
 The assembly code instructions occur in a
different order than in the C source code.
 Instructions 2 and 3 compute the
expression z*48 by a combination of leal
and shift instructions.
 Line 5 computes the value of x+y.
 Line 6 computes the AND of t1 and
0xFFFF.
Discussion
 The final multiply is computed by line 7.
 Since the destination of the multiply is
register %eax, this will be the value
returned by the function.
Special Arithmetic
Instructions
Special Arithmetic Instructions
 These instructions that support generating the full
64-bit product of two 32-bit numbers, as well as
integer division.
Special Arithmetic Instructions
 The imull instruction, a member of the imul
instruction class , is known as a “two-operand”
multiply instruction.
 It generates a 32-bit product from two 32-bit
operands
 When truncating the product to 32 bits, both
unsigned multiply and two’s-complement multiply
have the same bit-level behavior.
 IA32 also provides two different “one-operand”
multiply instructions to compute the full 64-bit
product of two 32-bit values—one for unsigned
(mull), and one for two’s-complement (imull)
multiplication.
Special Arithmetic Instructions
 For both of these, one argument must be in
register %eax, and the other is given as the
instruction source operand.
 The product is then stored in registers %edx
(high-order 32 bits) and %eax (low-order 32
bits).
 Although the name imull is used for two distinct
multiplication operations, the assembler can tell
which one is intended by counting the number of
operands.
Special Arithmetic Instructions
 Suppose we have signed numbers x and y stored
at positions 8 and 12 relative to %ebp, and we
want to store their full 64-bit product as 8 bytes
on top of the stack. The code would proceed as
follows:
Special Arithmetic Instructions
 Observe that the locations in which we store the
two registers are correct for a little-endian
machine—the high-order bits in register %edx
are stored at offset 4 relative to the low-order
bits in %eax. With the stack growing toward
lower addresses, that means that the low-order
bits are at the top of the stack.
Special Arithmetic Instructions
 The division and modulus operations are provided
by the single-operand divide instructions similar
to the single-operand multiply instructions.
 The signed division instruction idivl takes as
dividend the 64-bit quantity in registers %edx
(high-order 32 bits) and %eax (low-order 32
bits). The divisor is given as the instruction
operand. The instruction stores the quotient in
register %eax and the remainder in register
%edx.
Special Arithmetic Instructions
 Suppose we have signed numbers x and y stored
at positions 8 and 12 relative to %ebp, and we
want to store values x/y and x mod y on the
stack.
 gcc generates the following code:
Special Arithmetic Instructions
 The move instruction on line 1 and the arithmetic
shift on line 3 have the combined effect of setting
register %edx to either all zeros or all ones
depending on the sign of x.
 While the move instruction on line 2 copies x into
%eax. Thus, we have the combined registers
%edx and %eax storing a 64-bit, sign-extended
version of x.
 Following the idivl instruction, the quotient and
remainder are copied to the top two stack
locations (instructions 5 and 6).
Special Arithmetic Instructions
 A more conventional method of setting up the
divisor makes use of the cltd instruction.This
instruction sign extends %eax into %edx. With
this instruction, the code becomes
QUESTIONS
 ??????????????????????????

Co&al lecture-05

  • 1.
    COMPUTER ORGANIZATION AND ASSEMBLYLANGUAGE LECTURE-5-MACHINE LEVEL PROGRAMMING-II MUHAMMAD HAFEEZ DEPARTMENT OF COMPUTER SCIENCE GC UNIVERSITY LAHORE
  • 2.
    Data Formats  Dueto its origins as a 16-bit architecture that expanded into a 32-bit one, Intel uses the term “word” to refer to a 16-bit data type.  Based on this, they refer to 32-bit quantities as “double words.”  They refer to 64-bit quantities as “quad words.”  Most instructions we will encounter operate on bytes or double words.
  • 3.
    Data Formats  Mostof the common data types are stored as double words. This includes both regular and long int’s, whether or not they are signed.  All pointers (such as char *) are stored as 4-byte double words. Bytes are commonly used when manipulating string data.
  • 4.
    Data Formats  Morerecent extensions of the C language include the data type long long, which is represented using 8 bytes.  However, IA32 does not support this data type in hardware. But, the compiler must generate sequences of instructions that operate on these data 32 bits at a time
  • 5.
    Data Formats  Morerecent extensions of the C language include the data type long long, which is represented using 8 bytes.  However, IA32 does not support this data type in hardware. But, the compiler must generate sequences of instructions that operate on these data 32 bits at a time
  • 6.
    Data Formats  Morerecent extensions of the C language include the data type long long, which is represented using 8 bytes.  However, IA32 does not support this data type in hardware. But, the compiler must generate sequences of instructions that operate on these data 32 bits at a time
  • 7.
    Data Formats  Floating-pointnumbers come in three different forms: single-precision (4-byte) values, corresponding to C data type float  Double-precision (8-byte) values, corresponding to C data type double;  Extended-precision (10-byte) values .  Gcc uses the data type long double to refer to extended-precision floating-point values. It also stores them as 12-byte quantities to improve memory system performance, as will be discussed later. Using the long double data type (introduced in ISO C99) gives us access to the extended- precision capability of x86.
  • 8.
    Data Formats  Floating-pointnumbers come in three different forms: single-precision (4-byte) values, corresponding to C data type float  Double-precision (8-byte) values, corresponding to C data type double;  Extended-precision (10-byte) values .  Gcc uses the data type long double to refer to extended-precision floating-point values. It also stores them as 12-byte quantities to improve memory system performance, as will be discussed later. Using the long double data type (introduced in ISO C99) gives us access to the extended- precision capability of x86.
  • 9.
    Data Formats  Mostassembly code instructions generated by gcc have a single-character suffix denoting the size of the operand.  For example, the data movement instruction has three variants: movb (move byte), movw (move word), and movl (move double word).  The suffix ‘l’ is used for double words, since 32-bit quantities are considered to be “long words,” a holdover from an era when 16-bit word sizes were standard.
  • 10.
  • 11.
    Accessing Information  AnIA32 central processing unit (CPU) contains a set of eight registers storing 32-bit values.  These registers are used to store integer data as well as pointers.  Their names all begin with %e, but otherwise, they have peculiar names.  With the original 8086, the registers were 16 bits and each had a specific purpose. The names were chosen to reflect these different purposes. With flat addressing, the need for specialized registers is greatly reduced.
  • 12.
    Accessing Information  Forthe most part, the first six registers can be considered general-purpose registers with no restrictions placed on them.  We said “for the most part,” because some instructions use fixed registers as sources and/or destinations.  In addition, within procedures there are different conventions for saving and restoring the first three registers (%eax, %ecx, and %edx) than for the next three (%ebx, %edi, and %esi). (detail will be discussed in procedures)
  • 13.
    Accessing Information  Thefinal two registers (%ebp and %esp) contain pointers to important places in the program stack. They should only be altered according to the set of standard conventions for stack management.  The low-order 2 bytes of the first four registers can be independently read or written by the byte operation instructions.
  • 14.
    Accessing Information  Thisfeature was provided in the 8086 to allow backward compatibility to the 8008 and 8080— two 8-bit microprocessors that date back to 1974.  When a byte instruction updates one of these single-byte “register elements,” the remaining 3 bytes of the register do not change.  Similarly, the low-order 16 bits of each register can be read or written by word operation instructions. This feature stems from IA32’s evolutionary heritage as a 16-bit microprocessor and is also used when operating on integers with size designator short.
  • 15.
    Some History: IA32Registers %eax %ecx %edx %ebx %esi %edi %esp %ebp %ax %cx %dx %bx %si %di %sp %bp %ah %ch %dh %bh %al %cl %dl %bl 16-bit virtual registers (backwards compatibility) general purpose accumulate counter data base source index destination index stack pointer base pointer Origin (mostly obsolete)
  • 16.
    %rsp x86-64 Integer Registers Can reference low-order 4 bytes (also low-order 1 & 2 bytes) %eax %ebx %ecx %edx %esi %edi %esp %ebp %r8d %r9d %r10d %r11d %r12d %r13d %r14d %r15d %r8 %r9 %r10 %r11 %r12 %r13 %r14 %r15 %rax %rbx %rcx %rdx %rsi %rdi %rbp
  • 17.
    Operand Specifiers  Mostinstructions have one or more operands.  specifying the source values and destination values performing an operation and the destination location into which to place the result .  IA32 supports a number of operand forms.  Source values can be given as constants or read from registers or memory.  Results can be stored in either registers or memory.
  • 18.
    Operand Specifiers  Thedifferent operand possibilities can be classified into three types.  The first type, immediate, is for constant values.  In ATT-format assembly code, these are written with a ‘$’ followed by an integer using standard C notation, for example, $-577 or $0x1F.  Any value that fits into a 32-bit word can be used, although the assembler will use 1- or 2- byte encodings whenever possible.
  • 19.
    Operand Specifiers  Thesecond type, register, denotes the contents of one of the registers, either one of the eight 32-bit registers (e.g., %eax) for a double-word operation, one of the eight 16-bit registers (e.g., %ax) for a word operation, or one of the eight single-byte register elements (e.g., %al) for a byte operation.
  • 20.
    Operand Specifiers  Thereare many different addressing modes allowing different forms of memory references. The most general form is Imm(E b ,E i ,s)  Such a reference has four components:  An immediate offset Imm, a base register E b , an index register E i , and a scale factor s.  The s must be 1, 2, 4, or 8.  The effective address is then computed as Imm + R[E b ]+ R[E i ] . s.  This general form is often seen when referencing elements of arrays.
  • 21.
  • 22.
    Data Movement Instructions Among the most heavily used instructions are those that copy data from one location to another.  The generality of the operand notation allows a simple data movement instruction to perform what in many machines would require a number of instructions.
  • 24.
    Data Movement Instructions We group the many different instructions into instruction classes, where the instructions in a class perform the same operation, but with different operand sizes.  For example, the mov class consists of three instructions: movb, movw, and movl. All three of these instructions perform the same operation; they differ only in that they operate on data of size 1, 2, and 4 bytes, respectively.
  • 25.
    Data Movement Instructions The instructions in the mov class copy their source values to their destinations.  The source operand designates a value that is immediate, stored in a register, or stored in memory.  The destination operand designates a location that is either a register or a memory address.  IA32 imposes the restriction that a move instruction cannot have both operands refer to memory locations.
  • 26.
    Data Movement Instructions Copying a value from one memory location to another requires two instructions—the first to load the source value into a register, and the second to write this register value to the destination.
  • 27.
    Data Movement Instructions The register operands for these instructions can be any of the eight 32- bit registers (%eax–%ebp) for movl, any of the eight 16-bit registers (%ax–%bp) for movw, and any of the single-byte register elements (%ah–%bh,%al–%bl) for movb.
  • 28.
    Data Movement Instructions The following mov instruction examples show the five possible combinations of source and destination types.  Recall that the source operand comes first and the destination second:
  • 29.
    Data Movement Instructions The following mov instruction examples show the five possible combinations of source and destination types.  Recall that the source operand comes first and the destination second:
  • 30.
    Data Movement Instructions Both the movs and the movz instruction classes serve to copy a smaller amount of source data to a larger data location, filling in the upper bits by either sign expansion (movs) or by zero expansion (movz).  With sign expansion, the upper bits of the destination are filled in with copies of the most significant bit of the source value. With zero expansion, the upper bits are filled with zeros.
  • 31.
    Data Movement Instructions Differencebetween movb and movsbl and movzbl?
  • 32.
  • 33.
  • 34.
    Data Movement Instructions The final two data movement operations are used to push data onto and pop data from the program stack.  The stack plays a vital role in the  handling of procedure calls.  We add data to a stack via a push operation and remove it via a pop operation, with the property that the value popped will always be the value that was most recently pushed and is still on the stack.
  • 35.
    Data Movement Instructions With IA32, the program stack is stored in some region of memory.  The stack grows downward such that the top element of the stack has the lowest address of all stack elements. (By convention, we draw stacks upside down, with the stack “top” shown at the bottom of the figure). The stack pointer %esp holds the address of the top stack element.
  • 36.
  • 37.
    Data Movement Instructions The pushl instruction provides the ability to push data onto the stack, while the popl instruction pops it. Each of these instructions takes a single operand—the data source for pushing and the data destination for popping.
  • 38.
    Data Movement Instructions Pushing a double-word value onto the stack involves first decrementing the stack pointer by 4 and then writing the value at the new top of stack address.  Therefore, the behavior of the instruction pushl %ebp is equivalent to that of the pair of instructions  subl $4,%esp ;Decrement stack pointer  movl %ebp,(%esp) ;Store %ebp on stack  Except that the pushl instruction is encoded in the machine code as a single byte, whereas the pair of instructions shown above requires a total of 6 bytes.
  • 39.
    Data Movement Instructions Popping a double word involves reading from the top of stack location and then incrementing the stack pointer by 4.  Therefore, the instruction popl %eax is equivalent to the following pair of instructions:  movl (%esp),%eax Read %eax from stack  addl $4,%esp Increment stack pointer
  • 40.
    Data Movement Instructions Since the stack is contained in the same memory as the program code and other forms of program data, programs can access arbitrary positions within the stack using the standard memory addressing methods.  For example, assuming the top most element of the stack is a doubleword, the instruction movl 4(%esp),%edx will copy the second double word from the stack to register %edx.
  • 41.
  • 42.
    Data Movement Example The details are omitted of the assembly code that allocates space on the run-time stack on procedure entry and deallocates it prior to return.The details of this set-up and completion code will be covered when we discuss procedure linkage. The code we are left with is called the “body.”
  • 43.
    Data Movement Example When the body of the procedure starts execution, procedure parameters xp and y are stored at offsets 8 and 12 relative to the address in register %ebp.  Instructions 1 and 2 read parameter xp from memory and store it in register %edx.
  • 44.
    Data Movement Example Instruction 2 uses register %edx and reads x into register %eax, a direct implementation of the operation x = *xp in the C program.  Later, register %eax will be used to return a value from this function, and so the return value will be x.  Instruction 3 loads parameter y into register %ecx. Instruction 4 then writes this value to the memory location designated by xp in register %edx, a directimplementation of the operation *xp = y.
  • 45.
    Data Movement Example Two features about this assembly code are worth noting.  First,we see that what we call “pointers” in C are simply addresses. Dereferencing a pointer involves copying that pointer into a register, and then using this register in a memory reference.  Second, local variables such as x are often kept in registers rather than stored in memory locations. Register access is much faster than memory access.
  • 46.
    Practice Problem  Assumevariables v and p declared with types  src_t v;  dest_t *p;  where src_t and dest_t are data types declared with typedef. We wish to use  the appropriate data movement instruction to implement the operation  *p = (dest_t) v;  where v is stored in the appropriately named portion of register %eax (i.e., %eax,  %ax, or %al), while pointer p is stored in register %edx.  For the following combinations of src_t and dest_t, write a line of assembly  code that does the appropriate transfer. Recall that when performing a cast that  involves both a size change and a change of “signedness” in C, the operation  should change the signedness first
  • 47.
  • 48.
  • 49.
    Arithmetic and Logical Instructions Most of the operations are given as instruction classes, as they can have different variants with different operand sizes.  (Only leal has no other size variants.)  For example, the instruction class add consists of three addition instructions: addb, addw, and addl, adding bytes, words, and double words, respectively.
  • 50.
    Arithmetic and Logical Instructions Indeed, each of the instruction classes shown has instructions for operating on byte, word, and double-word data.  The operations are divided into four groups: load effective address, unary, binary, and shifts. Binary operations have two operands, while unary operations have one operand.
  • 51.
    Arithmetic and Logical Instructions Load Effective Address:  The load effective address instruction leal is actually a variant of the movl instruction. It has the form of an instruction that reads from memory to a register, but it does not reference memory at all.  Its first operand appears to be a memory reference, but instead of reading from the designated location, the instruction copies the effective address to the destination.
  • 52.
    Arithmetic and Logical Instructions Load Effective Address:  This instruction can be used to generate pointers for later memory references.
  • 53.
    Arithmetic and Logical Instructions Load Effective Address:  Another Use (Arithmetic):  leal instruction can be used to compactly describe common arithmetic operations.  For example, if register %edx contains value x, then the instruction  leal 7(%edx,%edx,4), %eax  will set register %eax to 5x + 7.
  • 54.
    Arithmetic and Logical Instructions Unary and Binary Operations:  Operations in the second group are unary operations, with the single operand serving as both source and destination. This operand can be either a register or a memory location. For example, the instruction incl (%esp) causes the 4-byte element on the top of the stack to be incremented. This syntax is equivalent to C increment (++) and decrement (--) operators.
  • 55.
    Arithmetic and Logical Instructions Unary and Binary Operations:  The third group consists of binary operations, where the second operand is used as both a source and a destination. This syntax is reminiscent of the C assignment operators, such as x += y.  Observe, however, that the source operand is given first and the destination second.
  • 56.
    Arithmetic and Logical Instructions Unary and Binary Operations:  For example, the instruction subl %eax,%edx decrements register %edx by the value in %eax. (It helps to read the instruction as “Subtract %eax from%edx.”)  The first operand can be either an immediate value, a register, or a memory location. The second can be either a register or a memory location.
  • 57.
  • 58.
  • 59.
    Arithmetic and Logical Instructions Shift Instructions:  In shift instructions, the shift amount is given first, and the value to shift is given second.  Both arithmetic and logical right shifts are possible.  The shift amount is encoded as a single byte, since only shift amounts between 0 and 31 are possible (only the low-order 5 bits of the shift amount are considered). The shift amount is given either as an immediate or in the single byte register element %cl. (These instructions are unusual in only allowing this specific register as operand.)
  • 60.
    Arithmetic and Logical Instructions Shift Instructions:  There are two instructions for left shift : sal and shl. Both have the same effect, filling from the right with zeros.  The right shift instructions differ in that sar performs an arithmetic shift (fill with copies of the sign bit), whereas shr performs a logical shift (fill with zeros).  The destination operand of a shift operation can be either a register or a memory location. We denote the two different right shift operations as >> A (arithmetic) and >> L (logical).
  • 61.
    Discussion  Most ofthe instructions can be used for either unsigned or two’s complement arithmetic. Only right shifting requires instructions that differentiate between signed versus unsigned data. This is one of the features that makes two’s- complement arithmetic the preferred way to implement signed integer arithmetic.
  • 62.
  • 63.
    Discussion  Function argumentsx, y, and z are stored in memory at offsets 8, 12, and 16 relative to the address in register %ebp, respectively.
  • 64.
    Discussion  The assemblycode instructions occur in a different order than in the C source code.  Instructions 2 and 3 compute the expression z*48 by a combination of leal and shift instructions.  Line 5 computes the value of x+y.  Line 6 computes the AND of t1 and 0xFFFF.
  • 65.
    Discussion  The finalmultiply is computed by line 7.  Since the destination of the multiply is register %eax, this will be the value returned by the function.
  • 66.
  • 67.
    Special Arithmetic Instructions These instructions that support generating the full 64-bit product of two 32-bit numbers, as well as integer division.
  • 68.
    Special Arithmetic Instructions The imull instruction, a member of the imul instruction class , is known as a “two-operand” multiply instruction.  It generates a 32-bit product from two 32-bit operands  When truncating the product to 32 bits, both unsigned multiply and two’s-complement multiply have the same bit-level behavior.  IA32 also provides two different “one-operand” multiply instructions to compute the full 64-bit product of two 32-bit values—one for unsigned (mull), and one for two’s-complement (imull) multiplication.
  • 69.
    Special Arithmetic Instructions For both of these, one argument must be in register %eax, and the other is given as the instruction source operand.  The product is then stored in registers %edx (high-order 32 bits) and %eax (low-order 32 bits).  Although the name imull is used for two distinct multiplication operations, the assembler can tell which one is intended by counting the number of operands.
  • 70.
    Special Arithmetic Instructions Suppose we have signed numbers x and y stored at positions 8 and 12 relative to %ebp, and we want to store their full 64-bit product as 8 bytes on top of the stack. The code would proceed as follows:
  • 71.
    Special Arithmetic Instructions Observe that the locations in which we store the two registers are correct for a little-endian machine—the high-order bits in register %edx are stored at offset 4 relative to the low-order bits in %eax. With the stack growing toward lower addresses, that means that the low-order bits are at the top of the stack.
  • 72.
    Special Arithmetic Instructions The division and modulus operations are provided by the single-operand divide instructions similar to the single-operand multiply instructions.  The signed division instruction idivl takes as dividend the 64-bit quantity in registers %edx (high-order 32 bits) and %eax (low-order 32 bits). The divisor is given as the instruction operand. The instruction stores the quotient in register %eax and the remainder in register %edx.
  • 73.
    Special Arithmetic Instructions Suppose we have signed numbers x and y stored at positions 8 and 12 relative to %ebp, and we want to store values x/y and x mod y on the stack.  gcc generates the following code:
  • 74.
    Special Arithmetic Instructions The move instruction on line 1 and the arithmetic shift on line 3 have the combined effect of setting register %edx to either all zeros or all ones depending on the sign of x.  While the move instruction on line 2 copies x into %eax. Thus, we have the combined registers %edx and %eax storing a 64-bit, sign-extended version of x.  Following the idivl instruction, the quotient and remainder are copied to the top two stack locations (instructions 5 and 6).
  • 75.
    Special Arithmetic Instructions A more conventional method of setting up the divisor makes use of the cltd instruction.This instruction sign extends %eax into %edx. With this instruction, the code becomes
  • 76.