Credits and Disclaimers

Slides:



Advertisements
Similar presentations
Fabián E. Bustamante, Spring 2007 Machine-Level Programming II: Control Flow Today Condition codes Control flow structures Next time Procedures.
Advertisements

CSC 221 Computer Organization and Assembly Language Lecture 21: Conditional and Block Structures: Assembly Programs.
Copyright © 2000, Daniel W. Lewis. All Rights Reserved. CHAPTER 5 MIXING C AND ASSEMBLY.
%rax %eax %rbx %ebx %rdx %edx %rcx %ecx %rsi %esi %rdi %edi %rbp %ebp %rsp %esp %r8 %r8d %r9 %r9d %r11 %r11d %r10 %r10d %r12 %r12d %r13 %r13d.
The CPU Revision Typical machine code instructions Using op-codes and operands Symbolic addressing. Conditional and unconditional branches.
Assembly Language for Intel-Based Computers
Flow Control Instructions
1 Homework Reading –PAL, pp Machine Projects –MP2 due at start of Class 12 Labs –Continue labs with your assigned section.
Low Level Programming Lecturer: Duncan Smeed Low Level Program Control Structures.
Machine-Level Programming II: Control Flow Topics Condition codes Conditional branches Loops Switch statements CS 105 “Tour of the Black Holes of Computing”
תרגול 5 תכנות באסמבלי, המשך
COMP 2003: Assembly Language and Digital Logic Chapter 2: Flags and Instructions Notes by Neil Dickson.
1 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition Carnegie Mellon Machine-Level Programming II: Control Carnegie Mellon.
Jumps, Loops and Branching. Unconditional Jumps Transfer the control flow of the program to a specified instruction, other than the next instruction in.
K.K. Leung Fall 2008Introductory Pentium Programming1 Pentium Architecture: Introductory Programming Kin K. Leung
1 Machine-Level Programming V: Control: loops Comp 21000: Introduction to Computer Organization & Systems March 2016 Systems book chapter 3* * Modified.
IA32: Control Flow Topics –Condition Codes Setting Testing –Control Flow If-then-else Varieties of Loops Switch Statements.
Assembly תרגול 7 תכנות באסמבלי, המשך. Condition Codes Single bit registers  CF – carry flag  ZF – zero flag  SF – sign flag  OF – overflow flag Relevant.
Machine-Level Programming 2 Control Flow Topics Condition Codes Setting Testing Control Flow If-then-else Varieties of Loops Switch Statements.
Precept 7: Introduction to IA-32 Assembly Language Programming
Machine-Level Programming 2 Control Flow
Samira Khan University of Virginia Feb 2, 2017
Credits and Disclaimers
Credits and Disclaimers
Credits and Disclaimers
Conditional Branch Example
Homework Reading Labs PAL, pp
CSC 221 Computer Organization and Assembly Language
Computer Architecture
Introduction to Intel x86-64 Assembly, Architecture, Applications, & Alliteration Xeno Kovah – 2014 xkovah at gmail.
Assembly Programming III CSE 410 Winter 2017
Assembly Programming III CSE 351 Spring 2017
Assembly Language Programming Part 2
Machine-Level Programming II: Arithmetic & Control
Machine-Level Programming II: Control
Chapter 3 Machine-Level Representation of Programs
Machine-Level Representation of Programs II
Machine-Level Programming II: Control Flow
Computer Architecture adapted by Jason Fritts then by David Ferry
x86 Programming II CSE 351 Autumn 2016
x86-64 Programming II CSE 351 Autumn 2017
Y86 Processor State Program Registers
Computer Organization and Assembly Language
x86-64 Programming II CSE 351 Winter 2018
Assembly Language: IA-32 Instructions
Instructor: David Ferry
Machine-Level Programming: Control Flow
Machine-Level Programming 2 Control Flow
Machine-Level Programming V: Control: loops Comp 21000: Introduction to Computer Organization & Systems Systems book chapter 3* * Modified slides from.
Fundamentals of Computer Organisation & Architecture
Machine-Level Programming 2 Control Flow
Machine-Level Representation of Programs III
Machine-Level Programming 2 Control Flow
Homework Reading Machine Projects Labs PAL, pp
x86 Programming III CSE 351 Autumn 2016
Carnegie Mellon Ithaca College
Chapter 3 Machine-Level Representation of Programs
Machine-Level Programming II: Control Flow
Carnegie Mellon Ithaca College
Carnegie Mellon Ithaca College
Carnegie Mellon Ithaca College
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
Carnegie Mellon Ithaca College
Credits and Disclaimers
Credits and Disclaimers
Credits and Disclaimers
Credits and Disclaimers
Computer Architecture and Assembly Language
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.

Comparing Operands The compare instruction facilitates the comparison of operands: cmpl rightop, leftop The instruction performs a subtraction of its operands, discarding the result. The instruction sets flags in the machine status word register (EFLAGS) that record the results of the comparison: CF carry flag; indicates overflow for unsigned operations OF overflow flag; indicates operation caused 2's complement overflow SF sign flag; indicates operation resulted in a negative value ZF zero flag; indicates operation resulted in zero For our purposes, we will most commonly check these codes by using the various jump instructions.

Conditional Jump Instructions The conditional jump instructions check the relevant EFLAGS flags and jump to the instruction that corresponds to the label if the flag is set: # make jump if last result was: je label # zero jne label # nonzero js label # negative jns label # nonnegative jg label # positive (signed >) jge label # nonnegative (signed >=) jl label # negative (signed <) jle label # nonpositive (signed <=) ja label # above (unsigned >) jae label # above or equal (unsigned >=) jb label # below (unsigned <) jbe label # below or equal (unsigned <=).

C to Assembly: if . . . int y = 5; if ( x >= 0 ) { y++; } . . . gcc -S –m64 –O0 if.c . . . movl $5, -8(%rbp) cmpl $0, -4(%rbp) js .L1 addl $1, -8(%rbp) .L1: . . .

C to Assembly: if . . . movl $5, -8(%rbp) # y = 5 cmpl $0, -4(%rbp) # compare x to 0 js .L1 # goto .L1 if negative addl $1, -8(%rbp) # y++ .L1: . . . int y = 5; if ( x < 0 ) goto L1; y++; L1:

C to Assembly: if…else . . . int y = 5; if ( x >= 0 ) y++; else movl $5, -8(%rbp) cmpl $0, -4(%rbp) js .L4 addl $1, -8(%rbp) jmp .L3 .L4: subl $1, -8(%rbp) .L3: gcc -S –m64 –O0 ifelse.c

C to Assembly: if…else . . . movl $5, -8(%rbp) # y = 5 cmpl $0, -4(%rbp) # compare x to 0 js .L4 # goto .L2 if negative addl $1, -8(%rbp) # y++ jmp .L3 # goto .L3 after y++ .L4: subl $1, -8(%rbp) # y-- .L3: . . . int y = 5; if ( x < 0 ) goto L4; y++; goto L3; L4: y--; L3: gcc -S –m64 –O0 ifelse.c

C to Assembly: do…while . . . int y = 0; do { y++; x--; } while ( x > 0); . . . movl $0, -8(%rbp) # y = 0 .L2: addl $1, -8(%rbp) # y++ subl $1, -4(%rbp) # x-- cmpl $0, -4(%rbp) # compare x to 0 jg .L2 # goto .L2 if positive gcc -S –m64 –O0 dowhile.c

C to Assembly: do…while . . . movl $0, -8(%rbp) # y = 0 .L2: addl $1, -8(%rbp) # y++ subl $1, -4(%rbp) # x-- cmpl $0, -4(%rbp) # compare x to 0 jg .L2 # goto .L2 if positive . . . int y = 0; L2: y++; x--; if ( x > 0) goto L2; gcc -S –m64 –O0 dowhile.c

C to Assembly: while . . . int y = 0; while ( x > 0 ) { y++; x--; } movl $0, -8(%rbp) # y = 0 jmp .L2 # goto compare x to 0 # entry test .L3: addl $1, -8(%rbp) # y++ subl $1, -4(%rbp) # x-- .L2: cmpl $0, -4(%rbp) # compare x to 0 jg .L3 # goto loop entry if positive gcc -S –m64 –O0 while.c

C to Assembly: while . . . movl $0, -8(%rbp) # y = 0 jmp .L2 # goto compare x to 0 # entry test .L3: addl $1, -8(%rbp) # y++ subl $1, -4(%rbp) # x-- .L2: cmpl $0, -4(%rbp) # compare x to 0 jg .L3 # goto loop entry if positive . . . int y = 0; goto L2; L3: y++; x--; L2: if (x > 0) goto L3; Note that the compiler translated the C while loop to a logically-equivalent do-while loop. gcc -S –m64 –O0 while.c

Reverse Engineering: Assembly to C Let's consider a short assembly function: f: pushq %rbp movq %rsp, %rbp subq 20, %rsp movl %edi, -20(%rbp) movl $1, -4(%rbp) movl $2, -8(%rbp) jmp .L2 .L3: movl -4(%rbp), %eax imull -8(%rbp), %eax movl %eax, -4(%rbp) addl $1, -8(%rbp) .L2: movl -8(%rbp), %eax cmpl -20(%rbp), %eax jle .L3 leave ret . . . This is stack setup code; the compiler creates this; it is not represented in C. We're going to reconstruct an equivalent function in C. The first step will be to identify the things that do not translate to C… This is cleanup and return code; it corresponds to a return statement in C.

Reverse Engineering: Assembly to C The next step will be to identify variables… . . . f: ... movl %edi, -20(%rbp) movl $1, -4(%rbp) movl $2, -8(%rbp) jmp .L2 .L3: movl -4(%rbp), %eax imull -8(%rbp), %eax movl %eax, -4(%rbp) addl $1, -8(%rbp) .L2: movl -8(%rbp), %eax cmpl -20(%rbp), %eax jle .L3 We're going to reconstruct an equivalent function in C. The next step will be to identify variables…

Reverse Engineering: Assembly to C Variables will be indicated by memory accesses. . . . f: movl $1, -4(%rbp) movl $2, -8(%rbp) cmpl -20(%rbp), %eax Filtering out repeat accesses yields these assembly statements: There's an access to a variable on the stack at rbp - 4; this must be a local (auto) variable. Let's call it Local1 There's another access to a variable on the stack at rbp - 8; this must also be a local (auto) variable. Let's call it Local2. A parameter is passed in %edi and stored in rbp – 20; let's call it Param1.

Reverse Engineering: Assembly to C Now we'll assume the variables are all C ints, and considering that the first two accesses are initialization statements, so far we can say the function in question looks like: ______ f(int Param1) { int Local1 = 1; int Local2 = 2; . . . } And another clue is the statement that stores the value of the variable we're calling Local1 into the register eax (or rax) right before the function returns. That indicates what's returned and the return type: int f(int Param1) { int Local1 = 1; int Local2 = 2; . . . return Local1; }

Reverse Engineering: Assembly to C Now, there are two jump statements, a comparison statement, and two labels, all of which indicate the presence of a loop… . . . f: jmp .L2 .L3: .L2: movl -8(%rbp), %eax cmpl -20(%rbp), %eax jle .L3 The first jump is unconditional… that looks like a C goto. So, this skips the loop body the first time through… The comparison is using the parameter we're calling Param1 (first argument) and we see that the register eax is holding the value of the variable we're calling Local2 (second argument). Moreover, the conditional jump statement that follows the comparison causes a jump back to the label at the top of the loop, if Local2 <= Param1.

Reverse Engineering: Assembly to C What we've just discovered is that there is a while loop: . . . f: jmp .L2 .L3: .L2: movl -8(%rbp), %eax cmpl -20(%rbp), %eax jle .L3 int f(int Param1) { int Local1 = 1; int Local2 = 2; . . . while (Local2 <= Param1){ } return Local1; The final step is to construct the body of the loop, and make sure we haven't missed anything else…

Reverse Engineering: Assembly to C Here's what's left, including the loop boundaries for clarity: . . . f: jmp .L2 .L3: movl -4(%rbp), %eax imull -8(%rbp), %eax movl %eax, -4(%rbp) addl $1, -8(%rbp) .L2: movl -8(%rbp), %eax cmpl -20(%rbp), %eax jle .L3 eax = Local1 eax = Local1 * Local2 Local1 = eax = Local1 * Local2 Local2 = Local2 + 1 And that will do it…

Reverse Engineering: Assembly to C Here's our function: int f(int Param1) { int Local1 = 1; int Local2 = 2; while (Local2 <= Param1) { Local1 = Local1 * Local2; Local2++; } return Local1; So, what is it computing… really?

Optimized Assembly The use of rep ret here is apparently due to issues with now-obsolete AMD processor branch prediction (Google to stackoverflow for a discussion). Apparently also, this is not present in the current release (8.1) of gcc… too bad CentOS doesn't incorporate that. Let's consider the same function, just lightly optimized using –O1: The is stack setup code has been omitted. There are only a few locals, and one parameter, so we don’t need the stack. f: cmpl $1, %edi jle .L4 movl $2, %edx movl $1, %eax .L3: imull %edx, %eax addl $1, %edx cmpl %edx, %edi jge .L3 rep ret .L4: ret . . . Registers are used instead of the stack. %edi holds Param1. %eax is used as Local1. %edx is used as Local2. The stack clean up code is also mostly gone. Only the ret instruction remains. More on this later.

Optimized Assembly Reproducing the earlier slide, we have the exact same pieces in fewer steps: f: cmpl $1, %edi jle .L4 movl $2, %edx movl $1, %eax .L3: imull %edx, %eax addl $1, %edx cmpl %edx, %edi jge .L3 rep ret .L4: ret . . . edx = Local2 eax = Local1 Local1 = eax = Local1 * Local2 Local2 = Local2 + 1 And that will do it…