1

I'm trying to write a Chip8 emulator with java and I've come across a question with the readAllBytes function in Java Files. When I loaded the bytes from the ROM I'm using to test into the "memory" array of my emulator, I tried to print those bytes to see if they are going into the memory correctly. I used Integer.toHexString to see those bytes as hex values and compare them to the actual file that I loaded with a hex editor, but the output that it gives me is strange:

First bytes of the file:

00 e0 a3 4c

Output from test:

0 ffffffe0 ffffffa3 4c

Code:

public void loadToMem(byte[] program) {
    for(int i = 0; i < program.length; i++) {
        this.memory[i+512] = program[i];
        System.out.println(Integer.toHexString(this.memory[i+512]));
    }
    this.initializeComponents();
}

Those values are just an error in the representation that Integer.toHexString gives and the values are being loaded correctly or are they really being loaded incorrectly? Why is it padding with f's?

logi-kal
  • 7,107
  • 6
  • 31
  • 43
  • 2
    Does this answer your question? [Java code To convert byte to Hexadecimal](https://stackoverflow.com/questions/2817752/java-code-to-convert-byte-to-hexadecimal) – Janez Kuhar Feb 13 '21 at 23:14
  • `e0` and `a3` are being interpreted as SIGNED single-byte integers. Because their high order bit is set (they have a value >= `80`), they represent negative values. Then, when you pass them to `Integer.toHexString`, the values are converted to 32-bit integers. This is why you see the `ffffff` having been added to the values, as it is what happens to a negative 8-bit integer when it is extended to a 32-bit integer. – CryptoFool Feb 13 '21 at 23:27
  • To convert a `byte[]` to hex string, you can also use `java.xml.bind.DatatypeConverter.printHexBinary(byte[] bits)` – Erik Feb 13 '21 at 23:32

1 Answers1

2

byte values in Java are signed 8-bit values. Because e0 and a3 each have their high order bit is set (they have a value >= 80 hex), they represent negative values. Then, when you pass them to Integer.toHexString, the values are extended to 32-bit values. What you are seeing is the equivalent 32-bit hex representation of these negative 8-bit values. This is called Two's Complement representation, which is what is used most often to represent signed integer values in a computer's memory.

With Two's Complement, a signed 8-bit (single byte) integer with hex value e0 has the decimal value -32. A signed 32-bit integer representation of -32 decimal is ffffffe0 in hex. When you extend a two's complement positive value to a wider representation, you pad with 0s. When you extend a negative twos complement value, you pad with ff values. This works the same way when extending a twos complement value to any number of bytes.

Most of us probably agreed with you that this is "a bit strange" the first time we saw how negative integers are interpreted in a computer's memory.

Here's a link to a simpler explanation of Two's Complement

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
CryptoFool
  • 21,719
  • 5
  • 26
  • 44
  • Thanks for answering, so those f's are just how the values are represented when printed by the Integer.toHexString right? the real values that are loaded didn't change? it's my first time trying to write an emulator, i still have doubts in some things, specially with java, like why a byte type doesn't accept the value 0xFF, 0xFF = 11111111 right? 8 bits, why a byte type doesn't accept it? – Cicero Alves Feb 14 '21 at 00:05
  • Yes, you're correct. They are the same value. In terms of assigning `0xFF` to a `byte` value failing, it must be because it is interpreting `0xFF` as an unsigned value, which would be 255. That value can't be represented by a `byte` value. A byte value represents decimal values `-128` to `127`. You can cast the constant to a `byte` value to fix this: `byte blah = (byte)0xff;`. Since bytes are signed values, `0xff` represents `-1` decimal – CryptoFool Feb 14 '21 at 00:13