x86-64 Programming II CSE 351 Winter 2018

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

Machine/Assembler Language Putting It All Together Noah Mendelsohn Tufts University Web:
Flow Control Instructions
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”
1 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition Carnegie Mellon Machine-Level Programming II: Control : Introduction.
Assembly Language. Symbol Table Variables.DATA var DW 0 sum DD 0 array TIMES 10 DW 0 message DB ’ Welcome ’,0 char1 DB ? Symbol Table Name Offset var.
1 Carnegie Mellon Assembly and Bomb Lab : Introduction to Computer Systems Recitation 4, Sept. 17, 2012.
תרגול 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.
K.K. Leung Fall 2008Introductory Pentium Programming1 Pentium Architecture: Introductory Programming Kin K. Leung
Lecture 7 Flow of Control Topics Finish Lecture 6 slides Lab 02 = datalab comments Assembly Language flow of control Test 1 – a week from wednesday February.
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.
1 Bryant and O’Hallaron, Computer Systems: A Programmer’s Perspective, Third Edition Carnegie Mellon Machine-Level Programming IV Control Comp 21000: Introduction.
Machine-Level Programming 2 Control Flow
Samira Khan University of Virginia Feb 2, 2017
Assembly Programming II CSE 351 Spring 2017
Homework Reading Labs PAL, pp
The Stack & Procedures CSE 351 Spring 2017
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
Machine-Level Representation of Programs II
Roadmap C: Java: Assembly language: OS: Machine code: Computer system:
Machine-Level Programming II: Control Flow
x86-64 Programming III & The Stack CSE 351 Winter 2018
x86 Programming II CSE 351 Autumn 2016
x86-64 Programming II CSE 351 Autumn 2017
Carnegie Mellon Machine-Level Programming II: Control : Introduction to Computer Systems 6th Lecture, Sept. 13, 2018.
Controlling Program Flow
x86-64 Programming III & The Stack CSE 351 Winter 2018
Roadmap C: Java: Assembly language: OS: Machine code: Computer system:
Flags Register & Jump Instruction
Assembly Programming III CSE 351 Spring 2017
Instructor: David Ferry
Processor Architecture: The Y86-64 Instruction Set Architecture
Machine-Level Programming: Control Flow
Machine-Level Programming 2 Control Flow
Machine-Level Programming 2 Control Flow
Processor Architecture: The Y86-64 Instruction Set Architecture
Assembly Programming II CSE 410 Winter 2017
Machine-Level Programming 2 Control Flow
Homework Reading Machine Projects Labs PAL, pp
The Stack & Procedures CSE 351 Winter 2018
x86 Programming III CSE 351 Autumn 2016
Flow Control Instructions
Carnegie Mellon Ithaca College
x86-64 Programming I CSE 351 Winter 2018
x86-64 Programming II CSE 351 Summer 2018
x86-64 Programming III CSE 351 Autumn 2018
x86-64 Programming I CSE 351 Winter 2018
x86-64 Programming II CSE 351 Autumn 2018
Machine-Level Programming II: Control Flow
X86 Assembly Review.
EECE.3170 Microprocessor Systems Design I
Carnegie Mellon Ithaca College
Carnegie Mellon Ithaca College
x86-64 Programming II CSE 351 Winter 2019
Carnegie Mellon Ithaca College
CS201- Lecture 8 IA32 Flow Control
Chapter 8: Instruction Set 8086 CPU Architecture
x86-64 Programming III CSE 351 Winter 2019
Carnegie Mellon Ithaca College
Credits and Disclaimers
Computer Architecture and Assembly Language
Presentation transcript:

x86-64 Programming II CSE 351 Winter 2018 Instructor: Mark Wyse Teaching Assistants: Kevin Bi Parker DeWilde Emily Furst Sarah House Waylon Huang Vinny Palaniappan http://xkcd.com/409/

Administrative Homework 2 (Ints and Floats) due Today! By 11:59 pm, no late submissions! x86-64 part due 1/29 GDB Tutorial Session Tomorrow, Thursday 1/25, 5 – 6 pm Room : SIG 134

x86 Control Flow Condition codes Conditional and unconditional branches Loops Switches Last time, we talked about moving data, arithmetic, and address computation Today, we will start our discussion on control flow

Control Flow Register Use(s) %rdi 1st argument (x) %rsi 2nd argument (y) %rax return value long max(long x, long y) { long max; if (x > y) { max = x; } else { max = y; } return max; max: ??? movq %rdi, %rax movq %rsi, %rax ret Consider this C code to find the max of two values Execution starts at the entry to the function By default execution goes from one instruction to the next So, how do we tell assembly code to only execute some of the instructions?

Control Flow Conditional jump Unconditional jump Register Use(s) %rdi 1st argument (x) %rsi 2nd argument (y) %rax return value long max(long x, long y) { long max; if (x > y) { max = x; } else { max = y; } return max; max: if x <= y then jump to else movq %rdi, %rax jump to done else: movq %rsi, %rax done: ret Conditional jump Unconditional jump With a branch instruction (also called a jump) If comparison is True, jump to else case Else, set max = x, then jump to done

Conditionals and Control Flow Conditional branch/jump Jump to somewhere else if some condition is true, otherwise execute next instruction Unconditional branch/jump Always jump when you get to this instruction Together, they can implement most control flow constructs in high-level languages: if (condition) then {…} else {…} while (condition) {…} do {…} while (condition) for (initialization; condition; iterative) {…} switch {…} Two types: conditional and unconditional Together, we can implement all the common C programming constructs

Processor State (x86-64, partial) Information about currently executing program Temporary data ( %rax, … ) Location of runtime stack ( %rsp ) Location of current code control point ( %rip, … ) Status of recent tests ( CF, ZF, SF, OF ) Single bit registers: Registers %rsp %r8 %r9 %r10 %r11 %r12 %r13 %r14 %r15 %rax %rbx %rcx %rdx %rsi %rdi %rbp Before we talk about how we implement conditional expressions, let’s revisit processor state: Talked about registers Mentioned %rip exists Now, add Condition Codes or “flags” How are these set and used? current top of the Stack Program Counter (instruction pointer) %rip CF ZF SF OF Condition Codes

Condition Codes (Implicit Setting) Implicitly set by arithmetic operations (think of it as side effects) Example: addq src, dst ↔ r = d+s CF=1 if carry out from MSB (unsigned overflow) ZF=1 if r==0 SF=1 if r<0 (assuming signed, actually just if MSB is 1) OF=1 if two’s complement (signed) overflow (s>0 && d>0 && r<0)||(s<0 && d<0 && r>=0) Condition Codes set by arithmetic operations OF = 1: set when src and dst have same sign and result has different sign Not set by leaq Not set by lea instruction (beware!) CF ZF SF OF Carry Flag Zero Flag Sign Flag Overflow Flag

Condition Codes (Explicit Setting: Compare) Explicitly set by Compare instruction cmpq src1, src2 cmpq a, b sets flags based on b-a, but doesn’t store CF=1 if carry out from MSB (used for unsigned comparison) ZF=1 if a==b SF=1 if (b-a)<0 (signed) OF=1 if two’s complement (signed) overflow (a>0 && b<0 && (b-a)>0) || (a<0 && b>0 && (b-a)<0) We can also explicitly set the condition codes First, using the compare instruction cmpq is similar to subq, but doesn’t store the result anywhere! CF ZF SF OF Carry Flag Zero Flag Sign Flag Overflow Flag

Condition Codes (Explicit Setting: Test) Explicitly set by Test instruction testq src2, src1 testq a, b sets flags based on a&b, but doesn’t store Useful to have one of the operands be a mask ZF=1 if a&b==0 SF=1 if a&b<0 (signed) CF and OF set to 0 Example: testq %rax, %rax Tells you if (+), 0, or (−) based on ZF and SF And second, we can use the test instruction testq is similar to andq, but doesn’t store the result anywhere! Example: commonly use test with both sources being the same CF ZF SF OF Carry Flag Zero Flag Sign Flag Overflow Flag

Using Condition Codes: Jump j* Instructions Jumps to target (an address) based on condition codes Instruction Condition Description jmp target 1 Unconditional je target ZF Equal / Zero jne target ~ZF Not Equal / Not Zero js target SF Negative jns target ~SF Nonnegative jg target ~(SF^OF)&~ZF Greater (Signed) jge target ~(SF^OF) Greater or Equal (Signed) jl target (SF^OF) Less (Signed) jle target (SF^OF)|ZF Less or Equal (Signed) ja target ~CF&~ZF Above (unsigned “>”) jb target CF Below (unsigned “<“) Bunch of different jump instructions First, unconditional Jump to target if the condition is True Don’t sweat the details or worry about remembering the condition codes for each instruction

Using Condition Codes: Set set* Instructions Set low-order byte of dst to 0 or 1 based on condition codes Does not alter remaining 7 bytes Instruction Condition Description sete dst ZF Equal / Zero setne dst ~ZF Not Equal / Not Zero sets dst SF Negative setns dst ~SF Nonnegative setg dst ~(SF^OF)&~ZF Greater (Signed) setge dst ~(SF^OF) Greater or Equal (Signed) setl dst (SF^OF) Less (Signed) setle dst (SF^OF)|ZF Less or Equal (Signed) seta dst ~CF&~ZF Above (unsigned “>”) setb dst CF Below (unsigned “<”) Can also set a register value from the condition codes. These set low-order byte of some register to 0 or 1, based on some combination of condition codes These have the same suffixes as the Jump instructions

Reminder: x86-64 Integer Registers Accessing the low-order byte: %rsp %spl %r8b %r8 %r9b %r9 %r10b %r10 %r11b %r11 %r12b %r12 %r13b %r13 %r14b %r14 %r15b %r15 %al %rax %bl %rbx %cl %rcx %dl %rdx %sil %rsi %dil %rdi %bpl %rbp Remember, we can access the low-order byte of any register!

Reading Condition Codes Register Use(s) %rdi 1st argument (x) %rsi 2nd argument (y) %rax return value Reading Condition Codes set* Instructions Set a low-order byte to 0 or 1 based on condition codes Operand is byte register (e.g. al, dl) or a byte in memory Do not alter remaining bytes in register Typically use movzbl (zero-extended mov) to finish job int gt(long x, long y) { return x > y; } Can set the low order byte of any register based on condition codes using the set instructions. Then, common to zero-extend the byte into the full register sets the upper bytes to 0 movz Be aware: order of the cmpq operands is backward first we do cmpq y, x, but then the setg is “true” if x > y. so, think of the cmpq as performing x – y, like a sub instruction, and then it makes more sense. cmpq %rsi, %rdi # setg %al # movzbl %al, %eax # ret

Reading Condition Codes Register Use(s) %rdi 1st argument (x) %rsi 2nd argument (y) %rax return value Reading Condition Codes set* Instructions Set a low-order byte to 0 or 1 based on condition codes Operand is byte register (e.g. al, dl) or a byte in memory Do not alter remaining bytes in register Typically use movzbl (zero-extended mov) to finish job int gt(long x, long y) { return x > y; } Can set the low order byte of any register based on condition codes using the set instructions. Then, common to zero-extend the byte into the full register sets the upper bytes to 0 movz Be aware: order of the cmpq operands is backward first we do cmpq y, x, but then the setg is “true” if x > y. so, think of the cmpq as performing x – y, like a sub instruction, and then it makes more sense. cmpq %rsi, %rdi # Compare x to y (x – y) setg %al # Set when > movzbl %al, %eax # Zero rest of %rax ret

Aside: movz and movs movz_ _ src, regDest Move with zero extension movs_ _ src, regDest Move with sign extension Copy from a smaller source value to a larger destination Source can be memory or register; Destination must be a register Fill remaining bits of dest with zero (movz) or sign bit (movs) movzSD / movsSD: S – size of source (b = 1 byte, w = 2) D – size of dest (w = 2 bytes, l = 4, q = 8) Example: movzbq %al, %rbx movz and movs have two width specifiers (b, w, l, q) for source and destination From smaller source to larger destination movs can also do a long to quad -> default behavior is zero extend 0x?? 0xFF ←%rax 0x00 0xFF ←%rbx

Aside: movz and movs movz_ _ src, regDest Move with zero extension movs_ _ src, regDest Move with sign extension Copy from a smaller source value to a larger destination Source can be memory or register; Destination must be a register Fill remaining bits of dest with zero (movz) or sign bit (movs) movzSD / movsSD: S – size of source (b = 1 byte, w = 2) D – size of dest (w = 2 bytes, l = 4, q = 8) Example: movsbl (%rax), %ebx Note: In x86-64, any instruction that generates a 32-bit (long word) value for a register also sets the high-order portion of the register to 0. Good example on p. 184 in the textbook. When moving to long, upper 4 bytes of the full 64-bit register are zeroed out 0x00 0x7F 0xFF 0xC6 0x1F 0xA4 0xE8 ←%rax ... 0x?? 0x80 ← MEM Copy 1 byte from memory into 8-byte register & sign extend it 0x00 0xFF 0x80 ←%rbx

Using Condition Codes: Jump j* Instructions Jumps to target (an address) based on condition codes Instruction Condition Description je target ZF Equal / Zero jne target ~ZF Not Equal / Not Zero js target SF Negative jns target ~SF Nonnegative jg target ~(SF^OF)&~ZF Greater (Signed) jge target ~(SF^OF) Greater or Equal (Signed) jl target (SF^OF) Less (Signed) jle target (SF^OF)|ZF Less or Equal (Signed) ja target ~CF&~ZF Above (unsigned “>”) jb target CF Below (unsigned “<“) Remember that conditional jumps occur based on how condition codes are set But, we can also interpret them as …

Choosing instructions for conditionals All arithmetic instructions set condition flags based on result of operation (op) Conditionals are comparisons against 0 addq (op) s, d je “Equal” d (op) s == 0 jne “Not equal” d (op) s != 0 js “Sign” (negative) d (op) s < 0 jns (non-negative) d (op) s >= 0 jg “Greater” d (op) s > 0 jge “Greater or equal” jl “Less” jle ”Less or equal” d (op) s <= 0 ja “Above” (unsigned >) d (op) s > 0U jb “Below” (unsigned <) d (op) s < 0U addq 5, (p) *p = *p + 5; addq 5, (p) je: *p+5 == 0 jne: *p+5 != 0 jg: *p+5 > 0 jl: *p+5 < 0 Comparisons against 0. Ink: Pick the op and outcome Pick the jump E.g.: Let’s say we want to addq 5, (p) Then, we can pick some comparison to perform against the result How about not equal to 0? If we want to check if *p + 5 != 0, select jne for the jump instruction

Choosing instructions for conditionals Reminder: cmp is like sub, test is like and Result is not stored anywhere cmpq 5, (p) je: *p == 5 . jne: *p != 5 . jg: *p > 5 . jl: *p < 5 . cmp a,b test a,b je “Equal” b == a b&a == 0 jne “Not equal” b != a b&a != 0 js “Sign” (negative) b-a < 0 b&a < 0 jns (non-negative) b-a >=0 b&a >= 0 jg “Greater” b > a b&a > 0 jge “Greater or equal” b >= a jl “Less” b < a jle ”Less or equal” b <= a b&a <= 0 ja “Above” (unsigned >) b&a > 0U jb “Below” (unsigned <) b&a < 0U testq a, a je: a == 0 . jne: a != 0 . jg: a > 0 . jl: a < 0 . First set flags explicitly using CMP or TEST, then jump appropriately: - use CMP for comparing two variables - use TEST for comparing with 0, e.g. with a mask Examples: Choose the op, then select the jump to use cmpq used when comparing two numbers testq used when comparing a value to itself or to a mask testb a, 0x1 je: aLSB == 0. jne: aLSB == 1.

Choosing instructions for conditionals %bl if (x < 3 && x == y) { return 1; } else { return 2; } cmp a,b test a,b je “Equal” b == a b&a == 0 jne “Not equal” b != a b&a != 0 js “Sign” (negative) b-a < 0 b&a < 0 jns (non-negative) b-a >=0 b&a >= 0 jg “Greater” b > a b&a > 0 jge “Greater or equal” b >= a jl “Less” b < a jle ”Less or equal” b <= a b&a <= 0 ja “Above” (unsigned >) b&a > 0U jb “Below” (unsigned <) b&a < 0U If either %al or %bl are false cmpq $3, %rdi setl %al T1: # x < 3 && x == y: movq $1, %rax ret T2: # else movq $2, %rax cmpq %rsi, %rdi sete %bl testb %al, %bl je T2 Can also test multiple conditions by performing comparisons, setting bytes in registers, then testing values in registers x -> %rdi y -> %rsi ret -> %rax %al = (x<3) %bl = (x==y) If either is false (je -> ZF == 0), then %al & %bl = 0 (jump to T2).

Choosing instructions for conditionals if (x < 3 && x == y) { return 1; } else { return 2; } cmp a,b test a,b je “Equal” b == a b&a == 0 jne “Not equal” b != a b&a != 0 js “Sign” (negative) b-a < 0 b&a < 0 jns (non-negative) b-a >=0 b&a >= 0 jg “Greater” b > a b&a > 0 jge “Greater or equal” b >= a jl “Less” b < a jle ”Less or equal” b <= a b&a <= 0 ja “Above” (unsigned >) b&a > 0U jb “Below” (unsigned <) b&a < 0U cmpq $3, %rdi setl %al T1: # x < 3 && x == y: movq $1, %rax ret T2: # else movq $2, %rax cmpq %rsi, %rdi sete %bl testb %al, %bl je T2 Go check out this link which is a compiler explorer. Can use different compilers and look at the output, or change optimization levels. For Compiler Explorer, show –Og option and contrast with –O1 option. https://godbolt.org/g/KntpyG

Question cmpq %rsi, %rdi jle .L4 cmpq %rsi, %rdi jg .L4 long absdiff(long x, long y) { long result; if (x > y) result = x-y; else result = y-x; return result; } Question Register Use(s) %rdi 1st argument (x) %rsi 2nd argument (y) %rax return value absdiff: __________________ # x > y: movq %rdi, %rax subq %rsi, %rax ret .L4: # x <= y: movq %rsi, %rax subq %rdi, %rax cmpq %rsi, %rdi jle .L4 cmpq %rsi, %rdi jg .L4 testq %rsi, %rdi jle .L4 testq %rsi, %rdi jg .L4 We’re lost… Answer: A x > y is equivalent to x <= y Need to jump over the x >y (if) branch if necessary (i.e., if x <= y). So, the compare and jump is setup to check x <= y cmpq %rsi, %rdi == x – y If x > y, then result of subtraction will be > 0. But, if x <= y (else branch), x – y will be less than or equal to 0. So, use cmpq to do x – y and set flags, and check for x – y <= 0 or x <= y using the jle instruction. Other choices: C and D: not the right type of test. We want to compare two values so we use cmpq which mimics subtraction B: this would jump to the y – x (else) branch if x > y, which is opposite of what we want!

Summary Control flow in x86 determined by status of Condition Codes Showed Carry, Zero, Sign, and Overflow, though others exist Set flags with arithmetic instructions (implicit) or Compare and Test (explicit) Set instructions read out flag values Jump instructions use flag values to determine next instruction to execute