Control Flow and Condition Codes in Assembly Language Programming
Explore how condition codes influence program execution in assembly language programming, focusing on control flow mechanisms, implicit and explicit setting of condition flags, and the utilization of single-bit registers like CF, SF, ZF, and OF. Understand the impact of arithmetic operations on condition codes and the importance of developing a mental model for program execution. Dive into x86 memory architecture, CPU registers, and instruction handling to enhance your understanding of low-level programming concepts.
Uploaded on Apr 12, 2025 | 0 Views
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
Machine-Level Programming III: Control or What Condition Your Condition is in CS154 Autumn 2019, Prof Chien Lecture 6 Sections 3.6 CMSC 15400 1
Carnegie Mellon Consider this code.. arith: leaq (%rdi,%rsi), %rax # t1 addq %rdx, %rax # t2 leaq (%rsi,%rsi,2), %rdx # y*3 salq $4, %rdx # t4 leaq 4(%rdi,%rdx), %rcx # t5 imulq %rcx, %rax # rval ret long arith (long x, long y, long z) { long t1 = x+y; long t2 = z+t1; long t3 = x+4; long t4 = y * 48; long t5 = t3 + t4; long rval = t2 * t5; return rval; } Register Use(s) %rdi Argument x %rsi Argument y %rdx Argument z %rax t1, t2, rval %rdx t4 %rcx t5 CMSC 15400 2
Carnegie Mellon Consider this code.. Assembly language doesn t support if, while, or for. long arith (long x, long y, long z) { long t1 = x+y; while (t1 > 0) { long t2 = z+t1; long t3 = x+4; long t4 = y * 48; t1 = t3 + t4; } long rval = t2 * t1; return rval; } Today Condition flags if conditional branches while and for loops Develop a mental model of program execution ( goto statement) CMSC 15400 3
Control Flow in x86 Memory CPU Addresses Registers Object Code Program Data OS Data PC Data Condition Codes Instructions ALU Stack CF ZF SF OF CMSC 15400 4
Carnegie Mellon Condition Codes (Implicit Setting) Single bit registers CF Carry Flag (for unsigned) SF Sign Flag (for signed) ZF Zero Flag OF Overflow Flag (for signed) Implicitly set (think of it as side effect) by arithmetic operations Example: addqSrc,Dest t = a+b CF set if carry out from most significant bit (unsigned overflow) ZF set if t == 0 SF set if t < 0 (as signed) OF setif two s-complement (signed) overflow (a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0) Not set by leaq instruction CMSC 15400 5
Carnegie Mellon Condition Codes (Explicit Setting: Test) Explicit Setting by Test instruction testqSrc2, Src1 testq b,a like computing a&b without setting destination Sets condition codes based on value of Src1 & Src2 Test sign of a value Useful to have one of the operands be a mask ZF set when a&b == 0 SF set when a&b < 0 CMSC 15400 6
Carnegie Mellon Condition Codes (Explicit Setting: Compare) Explicit Setting by Compare Instruction cmpqSrc2, Src1 cmpq b,a like computing a-b without setting destination CF set if carry out from most significant bit (used for unsigned comparisons) ZF set if a == b SF set if (a-b) < 0 (as signed) OF setif two s-complement (signed) overflow (a>0 && b<0 && (a-b)<0) || (a<0 && b>0 && (a-b)>0) a < b, iff SF ^ OF CMSC 15400 7
Carnegie Mellon Reading Condition Codes SetX Instructions Does not alter remaining 7 bytes SetX setl setne ~ZF sets setns ~SF setg setge ~(SF^OF) setl (SF^OF) setle (SF^OF)|ZF seta ~CF&~ZF setb CF %rsi Argument y Condition (SF^OF) Description Less (Signed) Not Equal / Not Zero Negative Nonnegative SF int less (long x, long y) { return x < y; } cmpq setl movzbq %al,%rax ret %rsi,%rdi # Compare x:y %al # Set when < # Zero rest of %rax ~(SF^OF)&~ZF Greater (Signed) Greater or Equal (Signed) Less (Signed) Less or Equal (Signed) Above (unsigned) Below (unsigned) x = 2, y = 3 0 Register Use(s) 0 1 SF = ? OF = ? ZF = ? %rdi Argument x 00 0 1 %rax Return value %rax %al CMSC 15400 8
Carnegie Mellon Reading Condition Codes SetX Instructions Does not alter remaining 7 bytes SetX sete setne ~ZF sets setns ~SF setg setge ~(SF^OF) setl (SF^OF) setle (SF^OF)|ZF seta ~CF&~ZF setb CF Condition ZF Description Equal / Zero Not Equal / Not Zero Negative Nonnegative SF cmpq b, a a > b, iff !(a<b) & a!=b ~(SF^OF)&~ZF Greater (Signed) Greater or Equal (Signed) Less (Signed) Less or Equal (Signed) Above (unsigned) Below (unsigned) cmpq b, a a < b, iff SF != OF CMSC 15400 9
Carnegie Mellon Today Control: Condition codes Conditional branches Loops CMSC 15400 10
Carnegie Mellon Conditional Branch Example jX jl Condition (SF^OF) Description Less (Signed) absdiff: cmpq %rsi, %rdi # x:y jl .L4 # jmp if x<y movq %rdi, %rax subq %rsi, %rax ret .L4: # x < y movq %rsi, %rax subq %rdi, %rax ret long absdiff (long x, long y) { long result; if (x >= y) result = x-y; else result = y-x; return result; } Register Use(s) %rdi Argument x %rsi Argument y %rax Return value CMSC 15400 11
Carnegie Mellon Jumping jX Instructions Jump to different part of code depending on condition codes jX jmp je jne js jns jg jge jl jle ja jb Condition 1 ZF ~ZF SF ~SF ~(SF^OF)&~ZF ~(SF^OF) (SF^OF) (SF^OF)|ZF ~CF&~ZF CF Description Unconditional Equal / Zero Not Equal / Not Zero Negative Nonnegative Greater (Signed) Greater or Equal (Signed) Less (Signed) Less or Equal (Signed) cmpq b, a a < b, iff SF != OF Above (unsigned) Below (unsigned) CMSC 15400 12
Carnegie Mellon Expressing with Goto Code C allows goto statement (Jump to position designated by label) absdiff: cmpq %rsi, %rdi # x:y jl .L4 # jmp if x<y movq %rdi, %rax subq %rsi, %rax ret .L4: # x < y movq %rsi, %rax subq %rdi, %rax ret long absdiff(long x, long y) { long result; if (x >= y) result = x-y; else result = y-x; return result; } long absdiff_j(long x, long y) { long result; int ntest = (x < y); if (ntest) goto Else; result = x-y; goto Done; Else: result = y-x; Done: return result; } jX of assembly equivalent to goto in C CMSC 15400 13
Carnegie Mellon General Conditional Expression Translation (Using Branches) C Code val = Test ? Then_Expr : Else_Expr; val = x>y ? x-y : y-x; Goto Version ntest = !Test; if (ntest) goto Else; val = Then_Expr; goto Done; Else: val = Else_Expr; Done: . . . Create separate code regions for then & else expressions Execute appropriate one CMSC 15400 14
Conditional Moves (cmov) One way to reduce impact of conditional branches Don t branch! cmovX{b,w,l,q) Condition Description cmove ZF Equal/zero cmovene ~ZF Not equal/ not zero Many more Just like jumps cmovX{b,w,l,q} S, D If X then copy value in S to D, otherwise nothing CMSC 15400 15
Conditional Move Example int result = 0; conditional_move: conditional_move(int a, int b) { movl movl cmpl cmovge %edx, %eax movl %eax, result ret 4(%esp), %eax 8(%esp), %edx %eax, %edx result = (a > b) ? a : b; } CMSC 15400 16
Bad Cases for Conditional Move Expensive Computations val = Test(x) ? Hard1(x) : Hard2(x); Both values get computed Only makes sense when computations are very simple Risky Computations val = p ? *p : 0; Both values get computed May have undesirable effects Computations with side effects val = x > 0 ? x*=7 : x+=3; Both values get computed Must be side-effect free CMSC 15400 17
Carnegie Mellon Today Control: Condition codes Conditional branches Loops CMSC 15400 18
Carnegie Mellon Do-While Loop Example C Code long pcount_do (unsigned long x) { long result = 0; do { result += x & 0x1; x >>= 1; } while (x); return result; } Goto Version long pcount_goto (unsigned long x) { long result = 0; loop: result += x & 0x1; x >>= 1; if(x) goto loop; return result; } Count number of 1 s in argument x Use conditional branch to either continue looping or to exit loop CMSC 15400 19
Carnegie Mellon Do-While Loop Compilation Goto Version long pcount_goto (unsigned long x) { long result = 0; loop: result += x & 0x1; x >>= 1; if(x) goto loop; return result; } Register Use(s) %rdi Argument x %rax result movl $0, %rax # result = 0 # loop: .L2: movq andl addq shrq jne ret %rdi, %rdx $1, %rdx %rdx, %rax %rdi .L2 # t = x & 0x1 # result += t # x >>= 1 # if (x) goto loop CMSC 15400 20
Carnegie Mellon General Do-While Translation Goto Version loop: Body if (Test) goto loop C Code do Body while (Test); Body: { Statement1; Statement2; Statementn; } CMSC 15400 21
Carnegie Mellon General While Translation Goto Version goto test; loop: Body test: if (Test) goto loop; done: Jump-to-middle (used with Og) While version while (Test) Body if (!Test) goto done; loop: Body if (Test) goto loop; done: Guided-do (used with O1) CMSC 15400 22
Carnegie Mellon Example Goto Version long pcount_goto_jtm (unsigned long x) { long result = 0; goto test; loop: result += x & 0x1; x >>= 1; test: if(x) goto loop; return result; } C Code long pcount_while (unsigned long x) { long result = 0; while (x) { result += x & 0x1; x >>= 1; } return result; } Jump-to-middle long pcount_goto_dw (unsigned long x) { long result = 0; if (!x) goto done; loop: result += x & 0x1; x >>= 1; if(x) goto loop; done: return result; } Guided-do CMSC 15400 23
Carnegie Mellon For Loop Form General Form Init i = 0 for (Init; Test; Update ) Test i < WSIZE Body #define WSIZE 8*sizeof(long) long pcount_for (unsigned long x) { size_t i; long result = 0; for (i = 0; i < WSIZE; i++) { unsigned bit = (x >> 1) & 0x1; result += bit; } return result; } Update i++ Body { unsigned bit = (x >> i) & 0x1; result += bit; } CMSC 15400 24
Carnegie Mellon For Loop For Version While Loop for (Init; Test; Update) Body While Version Init; while (Test ) { Body Update; } CMSC 15400 25
Carnegie Mellon For-While Conversion long pcount_for_while (unsigned long x) { size_t i; long result = 0; i = 0; while (i < WSIZE) { unsigned bit = (x >> 1) & 0x1; result += bit; i++; } return result; } Init i = 0 Test i < WSIZE Update i++ Body { unsigned bit = (x >> 1) & 0x1; result += bit; } CMSC 15400 26