Project #4 Notes, Fall 2006

This page is an accumulation of (we hope) helpful notes, hints, etc., that might be useful to you in doing Project #4.

  1. Floating-point numbers
  2. Returning 16-byte values


Floating-point numbers

There is no direct way to output floating-point numbers in assembler. Instead, output them as two 32-bit integers. For the ia32 architecture, the least-significant 32 bits come first, followed in the next four bytes by the most-significant 21 bits (of which the most significant is always 1 and there not included), an 11-bit exponent, and a sign bit (IEEE floating-point numbers are represented in sign-magnitude form rather than 2's complement).

In Java, you can get at these bits as a long value from a floating-point value X, with the call

Double.doubleToRawLongBits (X)

The low-order 32 bits are then (int) (X & 0xffffffffL) and the high-order bits are (int) (X >> 32).

Using GNU C++, there are a number of tricks for doing this. Again, if X is a variable of type double, you can use the (illicit) expression

*(long long int*)&X

to get the equivalent of doubleToRawLongBits.

Caution: When pushing a floating-point value (as opposed to laying out a floating-point literal in static storage with .long< pseudo-instructions), remember to push the most-significant part first, since the stack grows toward lower addresses.

Returning 16-byte values

Grr. There was a glitch in what we orginally said about returning the value of a function. When GCC passes a pointer to the return value space as its first argument, it also pops this pointer from the stack in the called program. What this means is that you should return from functions with

     ret $4
rather than
     ret
and should not pop those four bytes from the stack after the call. So, to call f(42), write
     subl  $16, %esp     # Reserve space for result
     movl  $0, 4(%esp)
     pushl $0            # Push 42
     pushl $42
     pushl $__obj_Int
     pushl $0
     pushl $0            # Static link
     leal  20(%esp), %eax # Return value address
     pushl %eax
     call  f
     addl  $20, %esp     # NOT $24
     ...
and return from f (and all your functions) with
     leave
     ret   $4
The only exception is that your _pyth_main routine probably should use just plain "ret", but I'll make sure it's harmless if it doesn't.

[CS164 Homework]    [CS164 Home Page]

Page was last modified on Tue Dec 5 19:48:53 2006.
Address comments and questions to cs164@eecs.berkeley.edu