I'm not sure if this question is going to make any sense, but I've messing around with writing basic assembly functions to use when I write C code (the C code is being output as 16 bit assembly, which is being output as a 16 bit raw binary). This is all part of my quest to become better at understanding/writing C and assembly, as well as my quest to understand how operating systems function at a conceptual level.
To make sure that my functions are working properly, I've been loading the raw binaries in real mode using the bios bootsector signature.
When I load the binary on virtualbox as a .flp, whether through an IDE controller or a floppy controller, the output on screen is completely as expected. There are two words with a space in between.
When, however, I go to load the same code on real machines using a USB stick, two letters in the first word are missing. The second word is written exactly as expected.
Is there any reason why there would be this kind of a discrepancy? I loaded the same code on three different real machines (not virtual box), and the same two letters in the first word were missing. I tried different USB sticks; I also loaded the raw image onto the USB with two different machines just to make sure.
I used the dd utility to write the .flp image I used on virtualbox (again, virtualbox has no problems with the output). I also used the dd utility to write the .flp image to the USB stick. I also wrote the .bin straight to the USB stick, and that did not make a difference.
I know there isn't anything wrong with the code itself, because it outputs perfectly on virtualbox. It just has those two letters oddly missing in the first word when booted onto real machines. Again, there are two words that are supposed to be output onto the screen.
The two missing characters are not weird characters that might not be universally supported; they're both lowercase letters.
Thanks for any help!
Final edit: This problem was being caused by the BIOS doing something nefarious to the binary program from bytes 2-48 in the program. From Michael's link in the comments, this appears to have something to do with the way that the BIOS deals with USB sticks on boot (which explains why it wasn't an issue when I was booting off of a floppy in virtual box). When I moved the program down by 48 bytes, the problem disappeared.
So my code looked something like (in as86 assembly syntax):
ORG 0x7c00
jmp main
.word 0x0000
ORG 0x7c30
main:
(calls putchar function 9 times)
putchar:
(function that prints function argument using int 0x10)
ORG 0x7DFE
.word 0xAA55
As I put in the comment, I'm curious to know why the BIOS would overwrite anything either in the first 512 bytes of the USB stick or in the 512 bytes of memory beginning at 0x7c00. I don't know which it is, whether it's overwriting on the USB stick before transferring the contents to memory, or whether it's overwriting the memory. I could find out by loading the program up once and then doing a hexdump on the binary in the USB after the boot-up load, but I haven't done that yet. At any rate, the overwriting at those locations just seems odd given that it's only by BIOS convention that the first 512 bytes are used (with the signature at the end), and it's only by BIOS convention that the CPU points to 0x7c00 following the load into memory. So I guess my point is that the BIOS certainly knows there are going to be instructions and data in those locations. So why wouldn't the BIOS do whatever it needs to do at some other location either on the USB stick or in the memory (depending on whether it's overwriting on the stick or rather in memory)?