CSCI 2400: Assembly Class 4

Status Flags


All processors provide a set of flags that are used to convey important information about the result of processor operations. For example, a frequently used flag is the zero flag which indicates whether the result of the last computation resulted in a value of zero. Understanding what these flags represent and how to use them is critical in writing anything beyond the most pasic programs- if/else statements, loops, and more complex structures all depend on these flags.

In today's class you will:

  1. Experiment with the zero flag
  2. Experiment with the carry flag
  3. Experiment with the overflow flag
  4. Finish writing a function to access the sign flag

Exercises

  1. Login to hopper.slu.edu- remember you can login with:

    ssh username@hopper.slu.edu

  2. Now, download a new program for today's class:

    wget http://cs.slu.edu/~dferry/courses/csci2400/asm/flags.s

  3. Like last time, I've added a few new functions:

    print_zf
    print_cf
    print_of
    print_sf

    I've also modified print_all so that the above four functions are called. However, be warned that the print_sf function is not finished yet! That's your job.

    Call the print_all function and take a look at the new additions.

  4. As said above, the zero flag (ZF) is used to indicate whether the previous arithmetic operation resulted in a zero value being stored to the destination operand. Try out the zero flag now, in your main program, write:

    movl	$1,	%eax
    subl	$1,	%eax
    call	print_all
    

    Flags are said to be ON or OFF. They're also said to be SET or UNSET or equivalently 1 or 0. What will be the state of the zero flag in the program printout above? Test it and copy-paste the results into your text file.

  5. Write a sequence of code that results the zero flag being OFF. Copy and paste your results.

  6. Suppose you had two variables X and Y. How could you test whether X and Y are equal using only the zero flag and basic arithmetic? (You don't need to write any code for this question.)

  7. Suppose you have a loop index I, and you're trying to write a for-loop that iterates 50 times. How could you implement this using only the zero flag and basic arithmetic? (You don't need to write any code for this question.)

  8. The carry flag (CF) is used with unsigned arithmetic only. This flag is set if an arithmetic operation would result in a bit being "carried out" of the operation. For example, if you were summing two 32-bit numbers and the "true math" result fits in 33 bits, then the carry flag is set. If the result would still fit within 32 bits, then the carry flag is off.

    Suppose that X is an immediate value in the code below:

    movl $0xFFFFF000, %eax
    addl X, %eax

    What values of X would result in the carry flag being set?

  9. Test your answer to the previous exercise. Demonstrate one value for which the carry bit is set, and one value for which the carry bit is off. Copy and paste your code and results.

  10. The overflow flag (OF) is used with signed arithmetic only. This flag is set if an arithmetic operation would result in signed integer overflow the most negative integer to the most positive integer. For example, for 32-bit arithmetic this means an overflow from -2147483648 to 2147483647 (or back).

    What is the maximum 32-bit signed integer, given in hexadecimal? (Hint: Which bits of a signed integer contribute positive value? Which bits contribute negative value?)

  11. Write an arithmetic expression that causes the overflow flag to be set. Copy and paste your code and results.

  12. The sign flag (SF) is used with signed arithmetic only. It tells you whether the result of an arithmetic operation results in a postive or negative value.

    The last part of this exercise is to finish a function that prints the value of the sign flag, called print_sf. You can find the partial function around line 200 of flags.s. In doing so, feel free to heavily borrow from the function print_zf, which prints the zero flag, right above it.

    Unfortunately, you can't access these flags directly. You can only access an entire 32-bit wide register full of all flags called the EFLAGS register. Then, you can use a bitwise-AND to select just the bit you want, and then use a right shift to move that bit into the least significant place so that, when printed, the value is either zero or one. The Sign Flag is in the 8th bit (0x80). So, to be explicit:

    1. Push the values of the EFLAGS register onto the stack with pushf.
    2. Pop those values into the EAX register with the pop instruction.
    3. Bitwise AND with the value 0x80 to get only the bit we're interested in.
    4. Right shift that bit into the least significant (first) position.
    5. Print the value of EAX with printf

    Once your function is complete you can call it directly or it will automatically be called as a part of the print_all function.

  13. Write two arithmetic expressions that cause the sign flag to be set and unset.

  14. Email your program to the instructor when you are done. Include your answers to each question in your email or in a text file and include them with your submission. These will count for credit as a homework assignment.