Credits and Disclaimers

Slides:



Advertisements
Similar presentations
University of Washington Procedures and Stacks II The Hardware/Software Interface CSE351 Winter 2013.
Advertisements

Inline Assembly Section 1: Recitation 7. In the early days of computing, most programs were written in assembly code. –Unmanageable because No type checking,
PC hardware and x86 3/3/08 Frans Kaashoek MIT
1 Function Calls Professor Jennifer Rexford COS 217 Reading: Chapter 4 of “Programming From the Ground Up” (available online from the course Web site)
Computer Architecture CPSC 321 E. J. Kim. Overview Logical Instructions Shifts.
Logical & shift ops (1) Fall 2007 Lecture 05: Logical Operations.
September 22, 2014 Pengju (Jimmy) Jin Section E
High-Level Language Interface Chapter 17 S. Dandamudi.
6.828: PC hardware and x86 Frans Kaashoek
Assembly Questions תרגול 12.
64-Bit Architectures Topics 64-bit data New registers and instructions Calling conventions CS 105 “Tour of the Black Holes of Computing!”
Chapter 8 Intermediate Code Zhang Jing, Wang HaiLing College of Computer Science & Technology Harbin Engineering University.
Assembly תכנות באסמבלי. Assembly vs. Higher level languages There are NO variables’ type definitions.  All kinds of data are stored in the same registers.
Machine-Level Programming: X86-64 Topics Registers Stack Function Calls Local Storage X86-64.ppt CS 105 Tour of Black Holes of Computing.
Assembly תרגול 5 תכנות באסמבלי. Assembly vs. Higher level languages There are NO variables’ type definitions.  All kinds of data are stored in the same.
Derived from "x86 Assembly Registers and the Stack" by Rodney BeedeRodney Beede x86 Assembly Registers and the Stack Nov 2009.
Microprocessors The ia32 User Instruction Set Jan 31st, 2002.
1 Carnegie Mellon Machine-Level Programming II: Arithmetic and Control Lecture, Feb. 28, 2012 These slides are from website which.
1 Carnegie Mellon Assembly and Bomb Lab : Introduction to Computer Systems Recitation 4, Sept. 17, 2012.
University of Washington x86 Programming I The Hardware/Software Interface CSE351 Winter 2013.
X86_64 programming Tutorial #1 CPSC 261. X86_64 An extension of the IA32 (often called x86 – originated in the Intel 8086 processor) instruction set to.
Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition Carnegie Mellon Instructor: San Skulrattanakulchai Machine-Level Programming.
1 Assembly Language: Function Calls Jennifer Rexford.
1 Machine-Level Programming V: Control: loops Comp 21000: Introduction to Computer Organization & Systems March 2016 Systems book chapter 3* * Modified.
Carnegie Mellon Machine-Level Programming II: Arithmetic & Control /18-243: Introduction to Computer Systems 6th Lecture, 5 June 2012 Carnegie Mellon.
Precept 7: Introduction to IA-32 Assembly Language Programming
Bitwise Operations C includes operators that permit working with the bit-level representation of a value. You can: - shift the bits of a value to the left.
Instruction Set Architecture
Credits and Disclaimers
Computer Architecture and Assembly Language
Assembly Language Programming IV: shift, struct, recursion
Data in Memory variables have multiple attributes symbolic name
Credits and Disclaimers
C function call conventions and the stack
CSCE 212 Computer Architecture
IA32 Processors Evolutionary Design
Chapter 12 Variables and Operators
Instructor: David Ferry
Homework In-line Assembly Code Machine Language
Introduction to Compilers Tim Teitelbaum
The Stack & Procedures CSE 351 Spring 2017
CS-401 Computer Architecture & Assembly Language Programming
The University of Adelaide, School of Computer Science
Machine-Level Programming II: Arithmetic & Control
Machine-Level Programming III: Procedures
Machine-Level Programming 1 Introduction
Computer Architecture adapted by Jason Fritts then by David Ferry
Machine-Level Programming III: Procedures /18-213/14-513/15-513: Introduction to Computer Systems 7th Lecture, September 18, 2018.
Instructor: David Ferry
Carnegie Mellon Machine-Level Programming III: Procedures : Introduction to Computer Systems October 22, 2015 Instructor: Rabi Mahapatra Authors:
MISP Assembly.
Comp Integers Spring 2015 Topics Numeric Encodings
Machine-Level Programming V: Control: loops Comp 21000: Introduction to Computer Organization & Systems Systems book chapter 3* * Modified slides from.
Machine-Level Programming III: Procedures Sept 18, 2001
Bitwise Operations C includes operators that permit working with the bit-level representation of a value. You can: - shift the bits of a value to the left.
Machine-Level Programming: Introduction
Bit-wise and bit-shift operators
Ithaca College Machine-Level Programming VII: Procedures Comp 21000: Introduction to Computer Systems & Assembly Lang Spring 2017.
Machine-Level Programming I: Basics Comp 21000: Introduction to Computer Organization & Systems Instructor: John Barr * Modified slides from the book.
02/02/10 20:53 Assembly Questions תרגול 12 1.
Machine-Level Programming V: Control: loops Comp 21000: Introduction to Computer Organization & Systems Systems book chapter 3* * Modified slides from.
CS201- Lecture 8 IA32 Flow Control
Ithaca College Machine-Level Programming VII: Procedures Comp 21000: Introduction to Computer Systems & Assembly Lang Spring 2017.
Credits and Disclaimers
Credits and Disclaimers
Credits and Disclaimers
Credits and Disclaimers
Credits and Disclaimers
Computer Architecture and System Programming Laboratory
Computer Architecture and System Programming Laboratory
Presentation transcript:

Credits and Disclaimers The examples and discussion in the following slides have been adapted from a variety of sources, including: Chapter 3 of Computer Systems 3nd Edition by Bryant and O'Hallaron x86 Assembly/GAS Syntax on WikiBooks (http://en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax) Using Assembly Language in Linux by Phillip ?? (http://asm.sourceforge.net/articles/linasm.html) The C code was compiled to assembly with gcc version 4.8.3 on CentOS 7. Unless noted otherwise, the assembly code was generated using the following command line: gcc –S –m64 -fno-asynchronous-unwind-tables –mno-red-zone –O0 file.c AT&T assembly syntax is used, rather than Intel syntax, since that is what the gcc tools use.

Shift Instructions Shifting the representation of an integer sall rightop, leftop leftop = leftop << rightop // C syntax! sarl rightop, leftop leftop = leftop >> rightop (preserves sign) shll rightop, leftop leftop = leftop << rightop (same as sall) shrl rightop, leftop leftop = leftop >> rightop (hi bits set to 0)

Left Shifts and Multiplication Shifting an integer operand to the left by k bits is equivalent to multiplying the operand's value by 2k: sall 1, %eax # eax = 2*eax sall 3, %edx # edx = 8*edx For example: edx 00000000 00000000 00000000 00000101 5 edx 00000000 00000000 00000000 00101000 40 Since general multiplication is much more expensive (in time) than shifting bits, we should prefer using a shift-left instruction when multiplying by a power of 2.

Right Shifts, Unsigned Operands, and Division Shifting an integer operand to the right by k bits might be expected to divide the operand's value by 2k: shrl 1, %eax # eax = eax / 2 ? Recall that shrl shifts in 0's on the left; so this will indeed perform integer division by 2, provided the value in eax is interpreted as an unsigned integer. For example, if we have an 8-bit unsigned representation of 25510, the instruction above would perform the following transformation: 1111 1111  0111 1111 So it would yield 12710, which is correct for integer division.

Right Shifts, Unsigned Operands, and Division But, the following will not yield the correct result for an unsigned integer: sarl 1, %eax # eax != eax / 2 For example, if we consider an 8-bit representation of 20010, the instruction above would produce this transformation: 1100 1000  1110 0100 So it would yield 22810, which is incorrect. The correct result would be 10010 which would be represented as 0110 0010. Note that the correct value would have been found by using shrl instead.

Right Shifts, Signed Operands, and Division Shifting a non-negative (signed) integer operand to the right by k bits will divide the operand's value by 2k: shrl 1, %eax # eax = eax / 2 sarl 1, %eax # eax = eax / 2 If eax holds a non-negative signed integer, the left-most bit will 0, and so both of these instructions will yield the same result. But, if the signed operand is negative, then the high bit will be 1. Clearly, shrl cannot yield the correct quotient in this case. Why?

Right Shifts, Signed Operands, and Division What about the following instruction, if eax holds a negative signed value? sarl 1, %eax # eax = eax / 2 sarl replicates the sign bit, so this will yield a negative result… But, suppose we have an 8-bit representation of -7: 1111 1001 Then applying an arithmetic right shift of 1 position yields: 1111 1100 That represents the value -4… is that correct? Mathematics says yes by the Division Algorithm: -7 = -4 * 2 + 1 Remainders must be >= 0! C says no: -7 = -3 * 2 + -1 -7 % 2 must equal -(7 % 2)

Logical Instructions There are the usual logical operations, applied bitwise: andl rightop, leftop leftop = leftop & rightop // C syntax! orl rightop, leftop leftop = leftop | righttop xorl rightop, leftop leftop = leftop ^ rightop notl op op = ~op

Arithmetic/Logic Example int arith(int x, int y, int z) { . . . } the Stack . . . rbp old value of rbp rsp frame for caller Calling a function causes the creation of a stack frame dedicated to that function. The frame pointer register, rbp, points to the beginning of the stack frame for the currently-running function. The stack pointer register, rsp, points to the last thing that was pushed onto the stack. (As an optimization, %rsp may or may not actually be updated. More on this later). fame for arith()

Arithmetic/Logic Example int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } the Stack . . . rbp + 8 return address rbp old value of rbp rbp – 4 t1 rbp – 8 t2 rbp - 12 t3 rbp - 16 t4 rbp - 20 x rbp - 24 y rbp – 28 Z autos within fn The first 6 function arguments are passed in registers, additional arguments are passed on the stack. The arguments stored in registers are often moved somewhere else on the stack before any computations. In this example: x is passed in register %edi and is moved to -20(%rbp). y is passed in register %esi and is moved to -24(%rbp). z is passed in register %edx and is moved to -28(%rbp).

Arithmetic/Logic Example int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } Mapping: address x rbp – 20 y rbp - 24 t1 rbp - 4 movl -24(%rbp), %eax # eax = y movl -20(%rbp), %edx # edx = x addl %edx, %eax # eax = x + y movl %eax, -4(%rbp) # t1 = x + y

Arithmetic/Logic Example int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } Mapping: address z rbp - 28 t2 rbp - 8 movl -28(%rbp), %edx # edx = z movl %edx, %eax # eax = z addl %eax, %eax # eax = z + z = 2z addl %edx, %eax # eax = 2z + z = 3z sall $4, %eax # eax = (3z) << 4 = 3z*16 = 48z movl %eax, -8(%rbp) # t2 = 48z

Arithmetic/Logic Example int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } Mapping: address t1 rbp - 4 t3 rbp - 12 movl -4(%rbp), %eax # eax = t1 movzwl $ax, %eax # eax = t1 & 0xFFFF movl %eax, -12(%rbp) # t3 = t1 & 0xFFFF

Aside: movzwl You may have noticed the movzwl instruction: . . . movzwl $ax, %eax # eax = t1 & 0xFFFF This moves a zero extended (z) word (16 bits) stored in %ax to %eax. And is equivalent to t1 & 0xFFFF since that will zero out the high 16 bits in %eax preserving the rest. We'll see other versions of this instruction later. There are different sizes (movzb) and there’s are signed variants (movsb). In this case, movzwl apparently offered a performance (or some other) advantage.

Arithmetic/Logic Example int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } Mapping: address t2 rbp - 8 t3 rbp - 12 t4 rbp - 16 movl -8(%rbp), %eax # eax = t2 imull -12(%rbp), %eax # eax = t2 * t3 movl %eax, -16(%rbp) # t4 = t2 * t3

Assembled Code .file "arith.c" .text .globl arith .type arith, @function arith: pushq %rbp # save old frame pointer movq %rsp, %rbp # move frame pointer to top movl %edi, -20(%rbp) # move arguments x, y, and z movl %esi, -24(%rbp) movl %edx, -28(%rbp) . . . movl -16(%rbp), %eax # set return value in eax popq %rbp # rsp = rbp; pop to rbp ret # return to caller .size arith, .-arith .ident "GCC: (GNU) 4.8.3 20140911 ..." .section .note.GNU-stack,"",@progbits gcc –O0 -S -Wall -m32 arith.c int arith(int x, int y, int z) { . . . int t4 = t2 * t3; return t4; }

Assembled Code . . . int arith(int x, int y, int z) { movl -24(%rbp), %eax # eax = y movl -20(%rbp), %edx # edx = x addl %edx, %eax # eax = x + y movl %eax, -4(%rbp) # t1 = x + y movl -28(%rbp), %edx # edx = z movl %edx, %eax # eax = z addl %eax, %eax # eax = z + z = 2z addl %edx, %eax # eax = 2z + z = 3z sall $4, %eax # eax = (3z) << 4 = 3z*16 = 48z movl %eax, -8(%rbp) # t2 = 48z int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; . . . }

Assembled Code . . . int arith(int x, int y, int z) { movl -4(%rbp), %eax # eax = t1 movzwl %ax, %eax # eax = t1 & 0xFFFF movl %eax, -12(%rbp) # t3 = t1 & 0xFFFF movl -8(%rbp), %eax # eax = t2 imull -12(%rbp), %eax # eax = t2 * t3 movl %eax, -16(%rbp) # t4 = t2 * t3 int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } int arith(int x, int y, int z) { . . . int t3 = t1 & 0xFFFF; int t4 = t2 * t3; }