Friday, April 19, 2013

JAVA_HOME annoyances on Linux (Ubuntu)

Just a quick writeup about an annoyance I come across every time I need to use Java on a Linux server. In my case I use the Ubuntu (12.04) server distro, so I'm unsure as to how this behaves on the other distro's. However, setting up the correct JAVA_HOME environment variable for a user never seems automatically done by the system or the package installers.

Tired of manually keeping track of the correct JAVA_HOME environment, I wrote this little script that is called in profile.d at logon time. It simply checks the /etc/alternatives/java symlink and resolves it. Then cuts of the /bin/java and optionally the /jre to construct the JAVA_HOME path. I know for sure that on some systems or in some situations this will not suffice, but on my system it does.

Put the following code in a file in /etc/profile.d (e.g. /etc/profile.d/java.sh):
JAVA_SEARCH="/etc/alternatives/java";

# Resolve link
INSTALLED_JAVA_ALTERNATIVES=`readlink -f ${JAVA_SEARCH}`

# Test if it is set
if [[ $INSTALLED_JAVA_ALTERNATIVES != $JAVA_SEARCH ]]; then
  # Test if the full path to java binary ends with /bin/java
  if [[ $INSTALLED_JAVA_ALTERNATIVES =~ .*/bin/java ]]; then
    JAVA_HOME_CANDIDATE=${INSTALLED_JAVA_ALTERNATIVES:0:-9}
    if [[ $JAVA_HOME_CANDIDATE =~ .*/jre ]]; then
      JAVA_HOME_CANDIDATE=${JAVA_HOME_CANDIDATE:0:-4}
    fi

    # Verify JVM
    if [[ -x ${JAVA_HOME_CANDIDATE}/bin/java ]]; then
      # Set the candidate as HOME
      export JAVA_HOME=${JAVA_HOME_CANDIDATE}
    fi
  fi
fi
When I happen to change the default Java JVM through the provided Ubuntu commands, this piece of scripting will make sure that the JAVA_HOME is correctly updated as well (after the next login). The script is very defensive, so if something isn't returned as expected then it will simply stop and not set a JAVA_HOME at all. Also, a user can still manually override the JAVA_HOME in his private profile.

As always, feel free to throw in a comment. The script is provided as-is and if your head explodes because of it, then don't blame me :)

Wednesday, January 2, 2013

32-bit division on an old school 8086 processor

During a 8086 assembler course, a student asked me how he could divide a 32-bit unsigned integer by a 16-bit unsigned integer. I knew that the answer was not to simply use the DIV instruction once, because of potential range limitations. Let me explain.

On the 8086 CPU the DIV instruction takes as input a 32-bit numerator in DX::AX and divides it by a denominator given as the operand of the instruction (a register or a memory address). After the division, AX holds the quotient, while DX contains the remainder of the division. More formal:


DIV   Unsigned divide
Syntax:  DIV    op8 (8-bit register or memory)
        DIV    op16 (16-bit register or memory)
Action:  If operand is op8, unsigned AL = AX / op8  and  AH = AX % op8
         If operand is op16, unsigned AX = DX::AX / op16  and  DX = DX::AX % op16
Flags:   OF=?, SF=?, ZF=?, AF=?, PF=?, CF=?

As shown, the DIV instruction performs a division and modulus operation at once. And, it is clear that one can provide certain values for the numerator when executing the DIV instruction that will result in an error. For example, with DX::AX set to 4000h::0000h, a division by 2 should give 2000h::0000h as the result, but the CPU cannot represent this value in the AX register. The quotient is too big and requires more than 16-bits to be able to represent it. In the worst case when a 32-bit number is divided by 1, then the quotient is that same 32-bit number. Therefore, when the quotient is too large to fit into AX, the CPU will generate a division overflow exception, just as it does with a division by zero.

It is obvious that a solution must exist to tackle this problem. Why else on earth would those Intel engineers in the seventies have designed a DIV instruction that takes 32-bit numerators at the input for 16-bit divisions?

At first, I searched the Internet for a solution. However, it did not take long to realize that either nobody, still working with 8086 assembler, understands or realizes the issue at hand, or that no-one was ever interested in providing a simple solution (I suspect the latter). So, I was forced to think it over myself and I decided to make this blog post about the solution for other people to use.

It appears that those Intel engineers did think about this problem and they provided everything necessary to divide big numbers by a 16-bit divisor. The DIV instruction design allows it to be chained easily with an unspecified amount of subsequent DIV instructions. This basically enables a programmer to use an arbitrary n * 16-bit number as numerator, by splitting the dividend in 32-bit blocks.

So here is a piece of plain old 8086 code (MASM-style). The actual div32 procedure performs a 32-bit unsigned integer division by chaining two DIV instructions. However, larger n * 16-bit numbers could be supported easily. Using LODSW and STOSW, the code becomes very clean and straightforward...

  ...<setup CX, SI, DI, DS, ES and FLAGS>...
  XOR   DX, DX ; set DX := 0
  LODSW        ; load the higher 16-bits into AX
  DIV   CX     ; divide DX::AX by CX
               ; leaves DX with remainder and AX with quotient
  STOSW        ; write out AX to result

  LODSW        ; load the lower 16-bits into AX
  DIV   CX     ; divide DX::AX by CX
               ; leaves DX with remainder and AX with quotient
  STOSW        ; write out AX to result
  ...<cleanup code>...


This LODSW, DIV, STOSW sequence can be repeated as many times as necessary in order to divide n * 16-bit numbers by a 16-bit divident.

I hope this small post will help some people to save some research time. Have fun coding on old-school 8086 :)

Note: The formatting on Google Docs for assembler code is not so great. Indentation is gone, and so is readability. Download the code and view it in a decent text editor to see indentation.