X86-64 Architecture Guide



Similar documents
x64 Cheat Sheet Fall 2015

CS412/CS413. Introduction to Compilers Tim Teitelbaum. Lecture 20: Stack Frames 7 March 08

Lecture 27 C and Assembly

64-Bit NASM Notes. Invoking 64-Bit NASM

Stack machines The MIPS assembly language A simple source language Stack-machine implementation of the simple language Readings:

Hacking Techniques & Intrusion Detection. Ali Al-Shemery arabnix [at] gmail

An Introduction to Assembly Programming with the ARM 32-bit Processor Family

A Tiny Guide to Programming in 32-bit x86 Assembly Language

Assembly Language: Function Calls" Jennifer Rexford!

Return-oriented programming without returns

Lecture 7: Machine-Level Programming I: Basics Mohamed Zahran (aka Z)

Chapter 7D The Java Virtual Machine

2) Write in detail the issues in the design of code generator.

Advanced Computer Architecture-CS501. Computer Systems Design and Architecture 2.1, 2.2, 3.2

CS:APP Chapter 4 Computer Architecture Instruction Set Architecture. CS:APP2e

Lecture Outline. Stack machines The MIPS assembly language. Code Generation (I)

MACHINE ARCHITECTURE & LANGUAGE

Instruction Set Architecture (ISA)

M A S S A C H U S E T T S I N S T I T U T E O F T E C H N O L O G Y DEPARTMENT OF ELECTRICAL ENGINEERING AND COMPUTER SCIENCE

Computer Organization and Architecture

Stack Allocation. Run-Time Data Structures. Static Structures

Where we are CS 4120 Introduction to Compilers Abstract Assembly Instruction selection mov e1 , e2 jmp e cmp e1 , e2 [jne je jgt ] l push e1 call e

a storage location directly on the CPU, used for temporary storage of small amounts of data during processing.

Notes on x86-64 programming

High-speed image processing algorithms using MMX hardware

CS61: Systems Programing and Machine Organization

Embedded Systems. Review of ANSI C Topics. A Review of ANSI C and Considerations for Embedded C Programming. Basic features of C

l C-Programming l A real computer language l Data Representation l Everything goes down to bits and bytes l Machine representation Language

1 Classical Universal Computer 3

Compilers. Introduction to Compilers. Lecture 1. Spring term. Mick O Donnell: michael.odonnell@uam.es Alfonso Ortega: alfonso.ortega@uam.

UNIVERSITY OF CALIFORNIA, DAVIS Department of Electrical and Computer Engineering. EEC180B Lab 7: MISP Processor Design Spring 1995

Instruction Set Architecture

Machine-Code Generation for Functions

ARM Cortex-M3 Assembly Language

C Compiler Targeting the Java Virtual Machine

Instruction Set Design

Bachelors of Computer Application Programming Principle & Algorithm (BCA-S102T)

Microprocessor & Assembly Language

Name: Class: Date: 9. The compiler ignores all comments they are there strictly for the convenience of anyone reading the program.

Habanero Extreme Scale Software Research Project

language 1 (source) compiler language 2 (target) Figure 1: Compiling a program

The Java Virtual Machine (JVM) Pat Morin COMP 3002

Base Conversion written by Cathy Saxton

The programming language C. sws1 1

Faculty of Engineering Student Number:

Interpreters and virtual machines. Interpreters. Interpreters. Why interpreters? Tree-based interpreters. Text-based interpreters

Lecture 22: C Programming 4 Embedded Systems

EC 362 Problem Set #2

Instruction Set Architecture

1 The Java Virtual Machine

PART B QUESTIONS AND ANSWERS UNIT I

Lecture 26: Obfuscation

Graded ARM assembly language Examples

COMP 356 Programming Language Structures Notes for Chapter 10 of Concepts of Programming Languages Implementing Subprograms.

Central Processing Unit Simulation Version v2.5 (July 2005) Charles André University Nice-Sophia Antipolis

Systems I: Computer Organization and Architecture

Notes on Assembly Language

Typy danych. Data types: Literals:

MPLAB TM C30 Managed PSV Pointers. Beta support included with MPLAB C30 V3.00

A single register, called the accumulator, stores the. operand before the operation, and stores the result. Add y # add y from memory to the acc

Intel Architecture Software Developer s Manual

ASSEMBLY LANGUAGE PROGRAMMING (6800) (R. Horvath, Introduction to Microprocessors, Chapter 6)

Handout 1. Introduction to Java programming language. Java primitive types and operations. Reading keyboard Input using class Scanner.

CSC 8505 Handout : JVM & Jasmin

THUMB Instruction Set

Machine-Level Programming II: Arithmetic & Control

Automating Mimicry Attacks Using Static Binary Analysis

PROBLEMS (Cap. 4 - Istruzioni macchina)

Introduction. Compiler Design CSE 504. Overview. Programming problems are easier to solve in high-level languages

Informatica e Sistemi in Tempo Reale

Introduction. Application Security. Reasons For Reverse Engineering. This lecture. Java Byte Code

Semantic Analysis: Types and Type Checking

Lecture 3 Addressing Modes, Instruction Samples, Machine Code, Instruction Execution Cycle

02 B The Java Virtual Machine

8. MACROS, Modules, and Mouse

Lecture 2. Binary and Hexadecimal Numbers

MICROPROCESSOR AND MICROCOMPUTER BASICS

Comp 255Q - 1M: Computer Organization Lab #3 - Machine Language Programs for the PDP-8

Chapter 5 Instructor's Manual

İSTANBUL AYDIN UNIVERSITY

Sources: On the Web: Slides will be available on:

PC Assembly Language. Paul A. Carter

Intel 8086 architecture

Z80 Instruction Set. Z80 Assembly Language

Programming Languages

More MIPS: Recursion. Computer Science 104 Lecture 9

An Introduction to the ARM 7 Architecture

CS101 Lecture 26: Low Level Programming. John Magee 30 July 2013 Some material copyright Jones and Bartlett. Overview/Questions

The 80x86 Instruction Set

Inside the Java Virtual Machine

Object Oriented Software Design

CPU Organization and Assembly Language

Overview of IA-32 assembly programming. Lars Ailo Bongo University of Tromsø

Chapter 4 Register Transfer and Microoperations. Section 4.1 Register Transfer Language

Software Vulnerabilities

Systems Design & Programming Data Movement Instructions. Intel Assembly

How It All Works. Other M68000 Updates. Basic Control Signals. Basic Control Signals

What to do when I have a load/store instruction?

Transcription:

X86-64 Architecture Guide For the code-generation project, we shall expose you to a simplified version of the x86-64 platform. Example Consider the following Decaf program: class Program { int foo(int x) { return x + 3; } void main() { int y; } y = foo(callout("get_int_035")); if (y == 15) { callout("printf_035", "Indeed! \'tis 15!\n"); } else { callout("printf_035", "What! %d\n", y); } } One compiled version of this program might look like this: foo: enter $0, $0 mov 16(%rbp), %rax add $3, %rax leave ret.globl main main: enter $(8 * 3), $0 call push get_int_035 %rax call foo

add $8, %rsp mov %rax, -8(%rbp) mov -8(%rbp), %r10 mov $15, %r11 cmp %r10, %r11 mov $0, %r11 mov $1, %r10 cmove %r10, %r11 mov %r11, -16(%rbp) mov -16(%rbp), %r10 mov $1, %r11 cmp %r10, %r11 je.fifteen push push call add jmp -8(%rbp) $.what printf_035 $(2 * 8), %rsp.fifteen_done.fifteen: push $.indeed call printf_035 add $(1 * 8), %rsp.fifteen_done: mov leave ret $0, %rax.indeed:.string "Indeed, \'tis 15!\n".what:.string "What! %d\n" We shall dissect this assembly listing carefully and relate it to the Decaf code. Note that this is not the only possible assembly of the program; it only serves as an illustration of some techniques you can use in this project phase. foo: enter $(8 * 0), $0

leave ret This is the standard boilerplate code for a function definition. The first line creates a label which names the entry point of the function. The following enter instruction sets up the stack frame. After the function is done with its actual work, the leave instruction restores the stack frame for the caller, and ret passes control back to the caller. Notice that one of the operands to enter is a static arithmetic expression. Such expressions are evaluated by the assembler and converted into constants in the final output. mov add 16(%rbp), %rax $3, %rax The purpose of $foo$ is to add 3 to its argument, and return the result. The arguments to a function are stored in its caller s frame, at positive quadword-aligned offsets from %rbp. The k-th argument is stored at location (8 + 8 k)(%rbp), so the mov instruction moves the value of the first argument into the %rax register. The next instruction increments the value in %rax by the literal or immediate value 3. Note that immediate values are always prefixed by a $. According to the calling convention, a function must place its return value in the %rax register, so foo has succeeded in returning x + 3..globl main main: enter $(8 * 3), $0 mov $0, %rax leave ret The.globl main directive makes the symbol main accessible to modules other than this one. This is important, because the C run-time library, which we link against, expects to find a main procedure to call at program startup. The enter instruction allocates space for three quadwords on the stack: one for a local variable and two for arguments passed to functions. At the end of the procedure, we set %rax to 0 to indicate that the program has terminated successfully.

call get_int_035 push %rax We call the get_int_035 function, which reads an integer from standard input and returns it. The function takes no arguments. The integer is returned in %rax, and we push it on the stack to be used as an argument to foo. Notice that we have optimized somewhat here: another valid approach would have been to store the return value in a local variable, and then load it back from there to push it as an argument. call add mov foo $8, %rsp %rax, -8(%rbp) With the one argument we have already pushed on the stack, we call foo. Once foo returns, we need to clean up the stack by removing the arguments we pushed on to it earlier. Here, we increase %rsp; we could also have performed a pop instruction. Finally, we save the return value stored in %rax to a temporary local variable. Local variables are stored at negative offsets from %rbp. mov -8(%rbp), %r10 mov $15, %r11 cmp %r10, %r11 mov $0, %r11 mov $1, %r10 cmove %r10, %r11 mov %r11, -16(%rbp) This sequence demonstrates how a comparison operation might be implemented using only two registers and temporary storage. We begin by loading the values to compare, i.e., the return value of foo and the literal 15, into registers. This is necessary because the comparison instructions only work on register operands. Then, we perform the actual comparison using the cmp instruction. The result of the comparison is to change the internal flags register. Our aim is to store a boolean value 1 or 0 in a local variable as the result of this operation. To set this up, we place the two possible values, 1 and 0, in registers %r10 and %r11.

Then we use the cmove instruction (read c-mov-e, or conditional move if equal) to decide whether our output value should be 0 or 1, based on the flags set by our previous comparison. The instruction puts the result in %r11. Finally, we store the boolean value from %r11 to a local variable at - 16(%rbp). mov -16(%rbp), %r10 mov $1, %r11 cmp %r10, %r11 je.fifteen jmp.fifteen_done.fifteen:.fifteen_done: This is the standard linearized structure of a conditional statement. We compare a boolean variable to 1, and perform a je (jump if equal) instruction which jumps to its target block if the comparison succeeded. If the comparison failed, je acts as a no-op. We mark the end of the target block with a label, and jump to it at the end of the fall-through block. Conventionally, such local labels, which do not define functions, are named starting with a period..indeed:.string "Indeed, \'tis 15!\n".what:.string "What! %d\n" These labels point to static strings defined in the program. They are used as arguments to functions. Reference This handout only mentions a small subset of the rich possibilities provided by the x86-64 instruction set and architecture. For a more complete (but still readable) introduction, consult The AMD64 Architecture Programmer s Manual, Volume 1: Application Programming.

Registers In the assembly syntax accepted by gcc, register names are always prefixed with %. For the first part of the project, we shall use only five of the x86-64 s sixteen general-purpose registers. All of these registers are 64 bits wide. Register Purpose Saved across calls %rax return value No %rsp stack pointer Yes %rbp base pointer Yes %r10 %r11 temporary No Instruction Set Each mnemonic opcode presented here represents a family of instructions. Within each family, there are variants which take different argument types (registers, immediate values, or memory addresses) and/or argument sizes (byte, word, double-word, or quad-word). The former can be distinguished from the prefixes of the arguments, and the latter by an optional one-letter suffix on the mnemonic. For example, a mov instruction which sets the value of the 64-bit %rax register to the immediate value 3 can be written as movq $3, %rax Immediate operands are always prefixed by $. Un-prefixed operands are treated as memory addresses, and should be avoided since they are confusing. For instructions which modify one of their operands, the operand which is modified appears second. This differs from the convention used by Microsoft s and Borland s assemblers, which are commonly used on DOS and Windows. Opcode Copying values mov src, dest cmove %src, %dest cmovne %src, %dest cmovg %src, %dest cmovl %src, %dest cmovge %src, %dest cmovle %src, %dest Description Copies a value from a register, immediate value or memory address to a register or memory address. Copies from register %src to register %dest if the last comparison operation had the corresponding result (cmove: equality, cmovne: inequality, cmovg: greater, cmovl: less, cmovge: greater or equal, cmovle: less or equal).

Stack management enter $x, $0 leave push src pop dest Control flow jmp target je target jne target Arithmetic and logic add src, dest sub src, dest imul src, dest idiv src, dest shr src, dest shl src, dest ror src, dest cmp src, dest Sets up a procedure s stack frame by first pushing the current value of %rbp on to the stack, storing the current value of %esp in %ebp, and finally decreasing %esp to make room for x quadwordsized local variables. Removes local variables from the stack frame by restoring the old values of %rsp and %rbp. Decreases %rsp and places src at the new memory location pointed to by %rsp. Here, src can be a register, immediate value or memory address. Copies the value stored at the location pointed to by %rsp to dest and increases %rsp. Here, dest can be a register or memory location. Jump unconditionally to target, which is specified as a memory location (for example, a label). Jump to target if the last comparison had the corresponding result (je: equality; jne: inequality). Add src to dest. Subtract src from dest. Multiply dest by src. Divide dest by src. Shift dest to the left or right by src bits. Rotate dest to the left or right by src bits. Set flags corresponding to whether dest is less than, equal to, or greater than src Stack Organization Global and local variables are stored on the stack, a region of memory that is typically addressed by offsets from the registers %rbp and %rsp. Each procedure call results in the creation of a stack frame where the procedure can store local variables and temporary intermediate values for that invocation. The stack is organized as follows:

Position Contents Frame 8n+16(%rbp) argument n Previous 16(%rbp) argument 0 8(%rbp) return address 0(%rbp) previous %rbp value -8(%rbp) 0(%rsp) locals and temps Current Calling Convention The caller pushes arguments on to the stack in reverse order. Finally, it pushes the return address and transfers control to the callee. The callee places its return value in %rax and is responsible for cleaning up its local variables as well as for removing the return address from the stack. It is not responsible for removing the arguments. The call, enter, leave and ret instructions make it easy to follow this calling convention. The standard calling convention used by C programs under Linux on x86-64 is a little different; see System V Application Binary Interface AMD64 Architecture Processor Supplement for details. Specifically, it optimizes calls by passing the first few arguments in registers instead of on the stack. As a result, your program cannot directly call out to arbitrary C procedures yet. Instead, we have provided two functions, printf_035 and get_int_035, which have been specifically adapted to this simplified convention. Function printf_035(fmt, arg1, ) get_int_035() Description Print a formatted string to standard output, exactly like printf(3). Read a single signed decimal integer from standard input and return its value.