Hi,
caligae wrote:Ok I figured out I made a stupid mistake. When linking I accidently used the command "ld --oformat=binary -Ttext=0x7c00 -o file2 file" instead of setting the text segment to zero. So the "f8" was double "7c". So the ljmp is also working now. I still dont understand how the call instruction works though, when it has not been relocated by the org directive. Even the un-relocated address appears not to be encoded in the call instruction.
For the call instruction, the value encoded in the instruction is an offset that is relative to IP. For example, the bytes 0xE8,0x34,0x12 would be "call the address of the next instruction plus 0x1234" and not "call 0x1234".
This means that the address of the code doesn't matter, in the same way that the value of "org" would have no effect in the formula "y = (org + z) - (org + x)". This also means that the assembler can figure it out and the linker probably doesn't need to know about call instructions at all (unless you're calling something in a different object file).
caligae wrote:One more thing, I see no mention of the ljmp mnemonic in any documentation. Is that gas specific?
Most documentation assumes Intel syntax mnemonics, but GAS uses AT&T syntax mnemonics. The "ljmp" would be "jmp (far)" in Intel's manual, and either "jmp far" or just "jmp" in most Intel syntax assemblers/disassemblers, tutorials, etc.
Cheers,
Brendan