Using address and operand overrides in real address mode

Status
Not open for further replies.

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
Hello,

In modern Intel systems, when in real address mode (the 16-bit mode that the old 8086 ran in) what happens when you use the 66h operand override and/or the 67h address override?

I know that in real mode there are no descriptor tables and no concept of protection, and, so there are no default operand/address bits in segment descriptors to be overridden.

So, in real mode do the override bytes do nothing, change the sizes to 32 bits, change the sizes to 8 bits, or throw an exception?

What happens?

Thanks.
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,283
3,905
75
Because what he says doesn't seem to be confirmed by the rest of the page.
 

exdeath

Lifer
Jan 29, 2004
13,679
10
81
Real mode is fixed at 16 bit.

You can actually enter into real mode 16 bit DOS debug and execute 32 bit code on 386+:

E 200

0200 66 B8 90 90 90 90 CB

U 200

0200 66 db 66
0201 B89000 mov ax, 9090
0204 90 nop
0205 90 nop
0206 CB ret

RIP 200

The result if you trace this for ONE instruction, on a 386 or higher:

AX=9090
IP=0206

Indicating the CPU executed a single 32 bit instruction in 16 bit real mode:

66B890909090 mov EAX, 90909090

A true 16 bit disassembly will see 66 as data/unknown (prefixes to add new functionality make use of previously undefined opcodes) and see 3 instructions even if the underlying CPU sees it as 32 bit.

If you execute this on a real 8088 the 66 does nothing or is undefined or crashes the CPU (there was no invalid opcode interrupt then) and if it proceeded would result a 16 bit move and 2 nops.

CB is for far return to terminate program and return to debug.exe monitor prompt (or was it near I dont remember!) to prevent you form continuing forever into uninitialized garbage past 0206 which will more than likely hang your real 8088 or cause your V86 DOS box in Win9x to eventually terminate with invalid instruction.
 
Last edited:

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
The result if you trace this for ONE instruction, on a 386 or higher:

AX=9090
IP=0206

Indicating the CPU executed a single 32 bit instruction in 16 bit real mode:

66B890909090 mov EAX, 90909090

OK, so the override temporarily converts, for one instruction, to 32-bit then.
 

exdeath

Lifer
Jan 29, 2004
13,679
10
81
OK, so the override temporarily converts, for one instruction, to 32-bit then.

If in real mode or a protected mode with CS pointing to a code segment descriptor with D bit set to 16 bit.

In native 32 bit the prefix toggles the opposite. If you assemble 32 bit code eg a Windows application and you enter "mov ax, 9090" the assembler will spit out 66 B8 90 90 adding the operand size prefix automatically.

Prefixes are per instruction.

Some CPUs have flags that you can set like 65816 that toggle operand sizes permanently until the next time you change it. SEP #$20/REP #$20 toggles accumulator size between 8 bit and 16 bit by setting/resetting the accumulator size flag in the flags/status register at will. This sort of thing makes disassembly and stepping/tracing a nightmare though.

Say you start dumping and assume 16 bit operands. Later you see something that sets 8 bit before jumping to the start. Great that was suppose to be 8 bit...So you disassembled code is entirely wrong and just complete jibberish where you're including the opcode of the next instruction as part of the previous instruction's parameter. And the byte after that was that opcodes parameter that you treated as the next instruction...Ugh horrible SNES flash backs.

X86 has default operand size in the code descriptor and must use a prefix override for any instruction that is to be otherwise. Obviously if you are in protected mode you likely don't have GDT rights to change your default operand size, though an OS could provide a syscall to allow you to change but this requires a new descriptor.

If your OS design had two equal descriptors of the same PL but diff default operand size and you had prior knowledge of their selector index you could you could far jump back and forth as needed to toggle the operand size.

Windows and Linux don't do this. But it's not worth it as x86's decades of onion layer compatibility already make complex opcode sequences with new prefixes and overrides an inescapable fact of life.
 
Last edited:
Reactions: Schmide

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
In native 32 bit the prefix toggles the opposite....Prefixes are per instruction.

Yes, I knew these things already.

I was only asking about real mode because Intel never explicitly mentioned it and I know, when in real mode, descriptors don't exist.

Ugh horrible SNES flash backs.

SNES?

You can't possibly mean the Super Nintendo Entertainment System, can you?

If so, how in God's name did you program a gaming console?

I mean the interface was so limited; you couldn't exactly plug a keyboard into the thing.

Did you somehow burn your own cartridges and run programs that way?

If your OS design had two equal descriptors of the same PL but diff default operand size and you had prior knowledge of their selector index you could you could far jump back and forth as needed to toggle the operand size.

I thought you said in the other thread you responded to that this wasn't allowed, that you can't make far calls if you're in user space.

You said that you can't access the GDT.
 

exdeath

Lifer
Jan 29, 2004
13,679
10
81
Yes, I knew these things already.

I was only asking about real mode because Intel never explicitly mentioned it and I know, when in real mode, descriptors don't exist.



SNES?

You can't possibly mean the Super Nintendo Entertainment System, can you?

If so, how in God's name did you program a gaming console?

I mean the interface was so limited; you couldn't exactly plug a keyboard into the thing.

Did you somehow burn your own cartridges and run programs that way?



I thought you said in the other thread you responded to that this wasn't allowed, that you can't make far calls if you're in user space.

You said that you can't access the GDT.

I said if you made your own OS or used something unconventional like Multics that embraces segmentation vs paging. Its not a x86 restriction, just not implemented in Windows and Linux among other operating systems. Modern day popular mainstream operating systems have all abandoned segment models and gone exclusively paging, and do their best to hide and ignore the bare minimum required segment setup that x86 protected mode imposes even for "flat mode".

You can't do a far a 16:32 far call in 32 bit Windows applications because there is only 1 valid ring 3 CS descriptor available to select and that's usually 0x001b and you obviously can't create your own GDT entry from ring 3.

As for SNES, or any console, all you need is an assembler and the ability to present a binary image in the cartridge slot at the reset vector. Type and assemble on PC of course, come on!

As for prefixes they have nothing to do with memory mode. Read the Intel topic again, 0x66 and 0x67 prefixes are valid in real, protected, and V86 mode segments. Since real mode is always 16 bit , the prefixes always mean 32 bit in real mode.
 
Last edited:

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
As for SNES, or any console, all you need is an assembler and the ability to present a binary image in the cartridge slot at the reset vector. Type and assemble on PC of course, come on!

OK. That makes sense.

But, still, the interface is through a cartridge.

You need to burn your code onto a ROM cartridge, pop it into the console, and run it.

Where did you find the hardware to flash a cartridge?

Were these cartridges ROMs or EEPROMs?

That is, did you have to have a fresh unflashed cartridge or could you take a pre-existing game and reflash its code away and replace it with yours?

Also, what type of processors do these gaming units have?
 

exdeath

Lifer
Jan 29, 2004
13,679
10
81
OK. That makes sense.

But, still, the interface is through a cartridge.

You need to burn your code onto a ROM cartridge, pop it into the console, and run it.

Where did you find the hardware to flash a cartridge?

Were these cartridges ROMs or EEPROMs?

That is, did you have to have a fresh unflashed cartridge or could you take a pre-existing game and reflash its code away and replace it with yours?

Also, what type of processors do these gaming units have?

When I did SNES I had a Double Pro Fighter copier unit, I could load my ROM onto floppy and loaded into RAM which sat in the cartridge address space and emulated cartridge access.

Now we have flash cards like Super Everdrive, SD2SNES, and PowerPak that are far more convenient. Some even have dev models with USB connectivity that let you load new code without having to constantly unplug the cartridge over and over.

Production cartridges are mask ROM. It's literally just fused interconnects that permanently encode the data without any active storage logic.

Reverse engineering someone elses stuff in raw assembly is a PITA, esp when you have variable 8/16 bit operand sizes toggled anywhere (which makes disassembling crappy) and there is a ton of compression and interleaved code and data blocks with no labels and other things that make it non trivial.

CPU wise, NES is a 1.79 MHz 6502, SNES is a 65816 @ 3.58 Mhz (a 16 bit instruction and pin compatible upgrade of the 6502). Genesis is 68000. Gameboy Advance is ARM7. PS2 is MIPS and custom vector units. Dreamcast was Hitachi SH4. Gamecube is Power7. I think that's everything I've worked on for game consoles.
 

chrstrbrts

Senior member
Aug 12, 2014
522
3
81
When I did SNES I had a Double Pro Fighter copier unit, I could load my ROM onto floppy and loaded into RAM which sat in the cartridge address space and emulated cartridge access.

OK. So, you had liaison hardware.

Nintendo was OK with this technology?

Now we have flash cards like Super Everdrive, SD2SNES, and PowerPak that are far more convenient. Some even have dev models with USB connectivity that let you load new code without having to constantly unplug the cartridge over and over.

Are the game companies OK with this?

Production cartridges are mask ROM. It's literally just fused interconnects that permanently encode the data without any active storage logic.

I know very little about hardware at this point.

Reverse engineering someone elses stuff in raw assembly is a PITA, esp when you have variable 8/16 bit operand sizes toggled anywhere (which makes disassembling crappy)

Disassemblers can't handle prefixes?

CPU wise, NES is a 1.79 MHz 6502, SNES is a 65816 @ 3.58 Mhz...

That sounds abysmally slow.
 
Last edited:

exdeath

Lifer
Jan 29, 2004
13,679
10
81
OK. So, you had liaison hardware.

Nintendo was OK with this technology?



Are the game companies OK with this?

Idgaf. My house. My property.

Time to close this thread as it's delving into dubious legal and swearing territory -- Programming Moderator Ken g6
 
Last edited by a moderator:

exdeath

Lifer
Jan 29, 2004
13,679
10
81
Disassemblers can't handle prefixes?

65816 didn't use prefixes. You could toggle accumulator and operand size and index register size both independently and back and forth at will anywhere. Standard beginning to end linear disassembly doesn't work because you have no idea how to parse it. You have to basically psuedo execute and follow all branch paths to 100% code coverage to properly know when operand size charges and when a branch target should be 8 or 16 bit. This also had the side benefit of labeling data blocks too though by process of elimination.

If you just assumed 16 bit and dumped something, but find that the program toggles to 8 bit before jumping there out of order, your prior disassembly is now known to be completely wrong and nonsensical.

Prefixes or separate opcodes like Arm vs Thumb are far easier to disassemble and don't require an intelligent disassembler that has to actually walk 100% code coverage to be correct.
 
Last edited:
Status
Not open for further replies.
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |