.Open Assembly Language Conditionals and Loops . Motivation To look at the various loop structures and conditional control structures; and have an understanding how they are implemented in assembly language. . Introduction When working with control structures and loops in assembly language, the concepts are not much different than when working with them in high level languages. As with all aspects of assembly language, we are dealing with these same high level ideas at a much lower level. We have $loops, and conditional $control_structures to use just as in high level languages. loops::= $for | $for_increment | $for_decrement | $pre_test | $post_test loops control_structures::= $if | $if_else | $if_elseif_else | $switch_case for::= for some_index = low to high, some_index iterates from low to high incrementing by one each iteration until some_value is greater than high, see the following for an assembly language example in NASM: .As_is mov rcx, low ; rcx register commonly used for index counter .As_is lp: ... ; statements inside for loop .As_is inc rcx ; increment index by one .As_is cmp rcx, high ; compare rcx to high .As_is jle lp ; jump if less than or equal to lp (lp can be whatever loop label you want) .As_is ... ; code after the for loop for_increment::= for some_index = low to high step increment, some_index iterates from low to high incrementing by increment value each iteration until some_value is greater than high, see the following for an assembly language example in NASM: .As_is mov rcx, low ; rcx register commonly used for index counter .As_is lp: ... ; statements inside for loop .As_is add rcx, increment ; increment index by one .As_is cmp rcx, high ; compare rcx to high .As_is jle lp ; jump if less than or equal to lp (lp can be whatever loop label you want) .As_is ... ; code after the for loop for_decrement::= for some_index = high to low step decrement, some_index iterates from high to low decrementing by decrement value each iteration until some_value is less than low, see the following for an assembly language example in NASM: .As_is mov rcx, high ; rcx register commonly used for index counter .As_is lp: ... ; statements inside for loop .As_is add rcx, decrement ; increment index by one - use add if decrement is a negative value, sub if decrement is positive .As_is cmp rcx, low ; compare rcx to high .As_is jge lp ; jump if greater than or equal to lp (lp can be whatever loop label you want) .As_is ... ; code after the for loop pre_test::= high level loop construct, in which we test for a test condition before executing the code block inside the loop, looping whilest the condition is true. In assembly language, we could have the following for a pre-test loop: .As_is mov rcx, some_value .As_is lp: cmp rcx, test_value ; do our pre_test for some value to be less than test_value .As_is jg ext ; jump to label ext (exit) if greater than test_value .As_is ... ; code to execute when some_value is less than test_value .As_is inc rcx ; increment rcx, we could use an add rcx, increment value if increment is more than one .As_is jmp lp ; jump back to lp - this is okay until we get into superscalar programming, then it can be iffy... .As_is ext: ... ; code to execute after pre-test loop done post_test::= high level loop construct, in which we test for a test condition after executing the code block inside the loop, looping whilest the condition is true. In assembly language, we could have the following for a post-test loop: .As_is mov rcx, some_value .As_is lp: ... ; code to execute when some_value is less than test_value .As_is ... ; code to execute when some_value is less than test_value .As_is inc rcx ; increment rcx, we could use an add rcx, increment value if increment is more than one .As_is cmp rcx, test_value ; do our pre_test for some value to be less than test_value .As_is jle lp ; jump to label lp if less than or equal to test_value .As_is ... ; code to execute after pre-test loop done if::= if a condition is true, execute code block. In assembly language: .As_is cmp {reg|mem}, some_value ; compare a register or memory location with some_value .As_is j_cc ext ; jump to ext when condition code is evaluated to false .As_is ... ; code to execute when comparision and condition code are true .As_is ext: ... ; code to continue after if block if_else ::= if a condition is true, execute code block; else execute block for when condition is false. In assembly language: .As_is cmp {reg|mem}, some_value ; compare a register or memory location with some_value .As_is j_cc fls ; jump to fls when condition code is evaluated to false .As_is ... ; code to execute when comparision and condition code are true .As_is jmp ext ; jump over the false block (label with fls) to ext .As_is fls: ... ; code to execute if condition is false .As_is ... .As_is ext: ... ; code to continue after if/else blocks if_elseif_else::= if a condition is true, execute code, else if another condition is true, execute second code block, continuing with as many chained if conditions being true, followed by a closing else if all previous conditions are false. In assembly language: .As_is cmp {reg|mem}, some_value ; compare a register or memory location with some_value .As_is j_cc c1 ; jump to fls when condition code is evaluated to false .As_is ... ; code to execute when comparision and condition code are true .As_is jmp ext ; jump over the false block (label with fls) to ext .As_is c1: cmp {reg|mem}, some_value2 ; compare a register or memory location with some_value .As_is j_cc c2 ; jump to fls when condition code is evaluated to false .As_is ... .As_is jmp ext .As_is c2: cmp {reg|mem}, some_value3 ; compare a register or memory location with some_value .As_is j_cc fls ; jump to fls when condition code is evaluated to false .As_is ... .As_is jmp ext .As_is fls: ... ; code when all conditions are false .As_is ext: ... ; code to continue after if/else blocks switch_case::= test for different values of a variable, in assembly language {reg|mem} is the same variable through out the code block: .As_is cmp {reg|mem}, value1 ; switch variable value in reg or memory, same reg/memory location through out entire block .As_is jg c2 ; test case #2 if greater than, a jne would not allow us to fall through to next condition .As_is ; if needed .As_is ... ; code to execute for case #1 .As_is [jmp ext] ; this is an optional instruction, if we have a c/c++ style break; keyword, jump to ext, otherwise .As_is ; do not jump and have it fall through to the next case .As_is c2: cmp {reg|mem}, value2 ; {reg|mem} same as above, but testing for value2... .As_is jg c3 ; jump to c3 if value2 is smaller than {reg|mem} .As_is ... .As_is [jmp ext] .As_is c3: cmp {reg|mem}, value3 ; {reg|mem} same as above, but testing for value3... .As_is jg dft ; jump to default if greater .As_is ... .As_is [jmp ext] .As_is dft: ... ; default code block .As_is ... .As_is ext: ... ; code after switch block branching::= $jmp label, $j_cc label jmp::= jmp label - unconditionally jumps the instruction pointer/program execution to address located at label. j_cc::= j_condition_code label - jumps the instruction pointer/program execution to address located at label based on $j_condition_code. j_condition_code::= $jo, $jno, $jb, $jnae, $jae, $jnb, $je, $jz, $jne, $jnz, $jbe, $jna, $ja, $jnbe, $js, $jns, $jp, $jpe, $jnp, $jpo, $jl, $jnge, $jge, $jnl, $jle, $jng, $jg, $jnle, $jcxz, $jecxz, $jrcxz jo::= jo label, jumps to label if overflow (overflow flag set to one) jno::= jno label, jumps to label if not overflow (overflow flag set to zero) jb::= jb label, jumps to label if below (carry flag set to one), some older disassemblers may disassemble this as jc label jnae::= jnae label, jumps to label if not above or equal (carry flag set to one), same as $jb. jae::= jae label, jumps to label if above or equal (carry flag set to zero), same as $jnb. jnb::= jnb label, jumps to label if not below (carry flag set to zero), some older disassemblers may disassemble this as jnc label, same as $jae. je::= je label, jump to label if equal (zero flag set to one), same as $jz jz::= jz label, jump to label if zero (zero flag set to one), same as $je jne::= jne label, jump to label if not equal (zero flag set to zero), same as $jnz jnz::= jnz label, jump to label if not zero (zero flag set to zero), same as $jne jbe::= jbe label, jump to label if below or equal (zero flag set to one OR carry flag set to one), same as $jna jna::= jna label, jump to label if not above (zero flag set to one OR carry flag set to one), same as $jbe jnbe::= jnbe label, jump to label if not below or equal (zero flag set to zero AND carry flag set to zero), same as $ja ja::= ja label, jump to label if above (zero flag set to zero AND carry flag set to zero), same as $jnbe js::= js label, jump to label if sign (sign flag set to one) jns::= jns label, jump to label if not sign (sign flag set to zero) jp::= jp label, jump to label if parity (parity flag set to one, even parity), same as $jpe jpe::= jpe label, jump to label if parity even (parity flag set to one), same as $jp jnp::= jnp label, jump to label if not parity (parity flag set to zero, odd parity), same as $jpo jpo::= jpo label, jump to label if parity odd (parity flag set to zero), same as $jnp jl::= jl label, jump to label if less than (sign bit AND overflow bit evaluated to one), same as $jnge jnge::= jnge label, jump to label if not greater than or equal (sign flag AND overflow flag evaluated to one), same as $jl jge::= jge label, jump to label if greater than or equal (sign flag is equal to overflow flag), same as $jnl jnl::= jnl label, jump to label if not less than (sign flag is equal to overflow flag), same as $jge jle::= jle label, jump to label if less than or equal (zero flag set to one OR (sign flag AND overflow flag evaluated to one)), same as $jng jng::= jng label, jump to label if not greater than (zero flag set to one OR (sign flag AND overflow flag evaluated to one)), same as $jle jg::= jg label, jump to label if greater (zero flag set to zero OR sign flag equal to overflow flag), same as $jnle jnle::= jnle label, jump to label if not less than or equal (zero flag set to zero OR sign flag equal to overflow flag), same as $jg jcxz::= jcxz label - a very expensive instruction in terms of clock cycles that jumps to label when cx = 0 jecxz::= jecxz label - a very expensive instruction in terms of clock cycles that jumps to label when ecx = 0 jrcxz::= jecxz label - a very expensive instruction in terms of clock cycles that jumps to label when rcx = 0 .Close Assembly Language Conditionals and Loops