+ Reply to Thread
Results 1 to 7 of 7

Thread: Intro to Intel Assembly Language: Part 4

  1. #1
    Join Date
    Oct 2007
    Location
    /dev/null
    Posts
    4,513
    Blog Entries
    8
    Rep Power
    59

    Intro to Intel Assembly Language: Part 4

    Hello, and welcome to my latest installment of my unofficial Intro to Intel Assembly Language series. Today we're going to learn how to make if-else and switch constructs in assembly language!

    First off, let's analyze a simple if statement:
    Code:
    if( condition ) {
        something();
    }
    foo();
    Clearly the something() will only execute if condition is true. If not, the computer jumps over the something() and resumes execution at foo(). Jumps...wait...didn't we learn how to do that in part 3? Why don't we rewrite it like this:

    Code:
        if( !condition )
            goto NEXT;
        something();
    NEXT:
        foo();
    Now we're getting somewhere. Even though this code uses the tabooed goto statement, this is essentially how it's implemented in assembly language. So how do we do this? Well, first we need to compare condition to true. Then we jump based on the result:

    Code:
    if( condition == FALSE)
        goto NEXT;
    So how do we compare stuff in assembly language? With the cmp instruction. cmp can be used just like add, sub etc; it follows all the same rules regarding restrictions on operands. However, it compares the two operands (subtracts dest from src) and sets the internal flags register with the results. You can then test this register and make decisions on where to jump. (Neither operand is modified, by the way.)
    But wait! How does the CPU know if I want to check to see if two operands are equal, or if one is greater than the other?
    Patience...all will be revealed.

    Samples:
    Code:
    ;these two are NOT necessarily equivalent!
    cmp    eax, edx
    cmp    edx, eax
    
    ;you can use constants on either side...
    cmp    0, eax
    cmp    DWORD PTR [esp], 0x0F85
    
    ;still can't use two memory operands, though.
    Now why are cmp eax,edx and cmp edx,eax not equivalent? Well...if you're testing for greater-than, eax > edx is not the same as edx > eax, now is it? Same principle.
    How do we check things, then?

    Conditional jumps. There are about sixteen:

    JE - Jump if equal
    JNE - Jump if not equal
    JA - Jump if above (unsigned >)
    JAE - Jump if above or equal (unsigned >=)
    JB - Jump if below (unsigned <)
    JBE - Jump if below or equal (unsigned <=)
    JG - Jump if greater than (signed >)
    JGE - Jump if greater than or equal (signed >=)
    JL - Jump if less than (signed <)
    JLE - Jump if less than or equal (signed <=)
    JO - Jump if overflow/underflow
    JNO - Jump if no overflow/underflow
    JPE - Jump if parity even (even number of bits set in resultant)
    JPO - Jump if parity odd (odd number of bits set in resultant)
    JC - Jump if carry (arithmetic operations)
    JNC - Jump if no carry (arithmetic operations)
    JS - Jump if sign bit set (i.e. negative)
    JNS - Jump if sign bit not set (i.e. positive)

    Some of these jump instructions also have aliases (alternate mnemonics that map to the same instruction). For example, JA has the alias JNBE, JG = JNLE, and so on. Some other aliases:

    JPE = JP
    JPO = JNP
    JE = JZ (jump if zero)
    JNE = JNZ (jump if not zero)

    Anyway, we shouldn't get too mired in these. Point is, now we can make decisions! Let's take the following snippet of code, and convert it to assembly language:
    Code:
    if(a == b)
        do_something();
    else
        do_something_else();
    foo();
    Assuming a=eax and b=ebx...
    Code:
        cmp    eax,ebx
        je    DO_TRUE
        jne    DO_FALSE
    DO_TRUE:
        call    do_something
        jmp    RESUME
    DO_FALSE:
        call    do_something_else
        jmp    RESUME
    RESUME:
        call    foo
    Clearly we can make some optimizations:
    Code:
        cmp    eax,ebx
        jne    DO_FALSE
        ;if we get here, then eax=ebx
        call    do_something
        jmp    RESUME
    DO_FALSE:
        call    do_something_else
        ;fall through
    RESUME:
        call    foo
    Yes, you can make several tests in a row, provided that you only do tests consecutively. Don't use other instructions, as some of them modify flags and that'll screw things up for you. Of course, if you know what you're doing, then go ahead. Just remember I warned you.

    Switch Statements
    The typical switch statement involves comparing one variable to a lot of values. It's very simple to code in assembly language:

    Code:
    cmp    eax, 1
    je    CASE_1
    cmp    eax, 2
    je    CASE_2
    ...
    CASE_1:
        ;blah...
        jmp    RESUME
    CASE_2:
        ;more blah...
        jmp    RESUME
    ...
    RESUME:
        ;move on with life
    Implementing a fall-through is also easy:
    Code:
    case 4:
       do_something();
       //fall through
    case 5:
        do_another();
        break;
    Code:
    cmp    eax,4
    je    CASE_4
    cmp    eax,5
    je    CASE_5
    ...
    CASE_4:
        call    do_something
    CASE_5:
        call    do_another
        jmp    RESUME
    ...
    RESUME:
        ;continue on
    If you want to implement a default statement, just stick the code after your tests.

    Code:
        cmp    eax,189024
        je    CASE_189024
    DEFAULT_CASE:
        ;code...
        jmp    RESUME
    ...
    CASE_189203:
        ...
    CASE_189204:
        ...
    RESUME:
        ;end of switch statement
    For Loops
    Well, this is pretty easy:
    Code:
    for(i = 0; i < 10; ++i)
        do_thing();
    foo();
    Code:
        mov    eax,0
    BEGIN_LOOP:
        cmp    eax, 10
        je    END_LOOP
        call    do_thing
        inc    eax
        jmp    BEGIN_LOOP
    END_LOOP:
        call    foo
    While Loops
    If you can do a for loop, you can do a while loop just as easily:
    Code:
    BEGIN_LOOP:
        ;assume we have a boolean in EAX
        cmp    eax, 0
        je    END_LOOP
            ;this is the inside of the loop
            ...
        jmp    BEGIN_LOOP
    END_LOOP:
    Do-While Loops
    This actually takes fewer instructions to implement:
    Code:
    BEGIN_LOOP:
        ;code inside the loop
        ;this is the condition we're testing
        cmp    eax, 0
        jne    BEGIN_LOOP
    END_LOOP:
    Tips and Tricks
    1) Instead of doing this:
    Code:
    ;compiles to 6 bytes
    cmp    eax, 0
    Do this:
    Code:
    ;compiles to 2 (sometimes 3) bytes
    or    eax,eax
    It's a fairly standard way of comparing something to zero; since or changes the flags, we can check to see if the result was zero or not. ORing anything with itself doesn't change it, so we don't have to worry about inadvertently modifying our data. Note that you can't do this with a memory operand, because you'd have two memory operands for one instruction, which is illegal.

    2) Instead of this:
    Code:
    mov    eax, 0
    Do this:
    Code:
    xor    eax,eax
    Again, we have the same restrictions as or eax,eax. The proof of why this works is left as an exercise to the reader.

    Well, that's all I have time for today. We'll continue learning assembly language with my next tutorial, where I will (most likely) explain functions, how to call them, how to pass arguments, and all that fun stuff. I don't know when I'll be able to post the next tutorial...but until then, good luck, and have fun learning ASM!

    Next In This Series
    Intro to Intel Assembly Language: Part 5
    Last edited by dargueta; 11-18-2010 at 07:19 PM.
    sudo rm -rf /

  2. CODECALL Circuit advertisement
    Join Date
    Always
    Location
    Advertising world
    Posts
    Many

     
  3. #2
    Join Date
    Jul 2006
    Posts
    16,491
    Blog Entries
    75
    Rep Power
    143

    Re: Intro to Intel Assembly Language: Part 4

    Well done, and very clear. As you are showing, ASM isn't that hard, it just pushes you to work at a lower level.
    Programming is a branch of mathematics.
    My CodeCall Blog | My Personal Blog

  4. #3
    Jordan Guest

    Re: Intro to Intel Assembly Language: Part 4

    Easy to read, easy to understand - the qualities of a well written tutorial! Nice work. +rep

  5. #4
    Join Date
    Jul 2006
    Location
    Amherst, New York, United States
    Posts
    6,277
    Blog Entries
    26
    Rep Power
    20

    Re: Intro to Intel Assembly Language: Part 4

    What IDE / compiler do you use / recommend?

  6. #5
    Join Date
    May 2008
    Posts
    2,126
    Blog Entries
    1
    Rep Power
    33

    Re: Intro to Intel Assembly Language: Part 4

    vim + nasm.

  7. #6
    Join Date
    Oct 2007
    Location
    /dev/null
    Posts
    4,513
    Blog Entries
    8
    Rep Power
    59

    Re: Intro to Intel Assembly Language: Part 4

    ConTEXT (Windows only) or SciTE (Linux) for editing, NASM for compiling.

    Welcome back, MeTh0Dz.
    sudo rm -rf /

  8. #7
    Join Date
    Aug 2009
    Location
    ~/
    Posts
    918
    Rep Power
    19

    Re: Intro to Intel Assembly Language: Part 4

    Good Tutorial +rep

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Intro to Intel Assembly Language: Part 9A
    By dargueta in forum Assembly Tutorials
    Replies: 4
    Last Post: 08-16-2010, 09:06 AM
  2. Intro to Intel Assembly Language: Part 8
    By dargueta in forum Assembly Tutorials
    Replies: 6
    Last Post: 07-15-2010, 09:21 AM
  3. Intro to Intel Assembly Language: Part 5
    By dargueta in forum Assembly Tutorials
    Replies: 6
    Last Post: 03-07-2010, 12:45 PM
  4. Intro to Intel Assembly Language: Part 7
    By dargueta in forum Assembly Tutorials
    Replies: 5
    Last Post: 12-30-2009, 02:17 PM
  5. Intro to Intel Assembly Language: Part 6
    By dargueta in forum Assembly Tutorials
    Replies: 3
    Last Post: 12-14-2009, 06:06 PM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts