flat assembler
Message board for the users of flat assembler.

Index > Heap > Can a 64bit processer run 16 bit programs?

Goto page Previous  1, 2
Author
Thread Post new topic Reply to topic
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
wow, there wasn't V86 mode on 286? In that case, I see why it sucked so bad :]
Post 15 Jun 2008, 12:57
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17279
Location: In your JS exploiting you and your system
revolution
vid wrote:
wow, there wasn't V86 mode on 286? In that case, I see why it sucked so bad :]
Yeah, it sucked like an insane vacuum cleaner on steroids.
Post 15 Jun 2008, 13:00
View user's profile Send private message Visit poster's website Reply with quote
System86



Joined: 15 Aug 2007
Posts: 77
System86
According to the fasm manual, it's possible to perform operations on 8 bit/16 bit registers (like al, ax, etc.) even in long mode (I think a special prefix is used by the CPU, like in 32 bit mode). You can access 16 bit register components in 32bit/64bit code in long mode, but you can't use vm86 code, so 16-bit DOS apps don't work.
Post 16 Jun 2008, 00:50
View user's profile Send private message Reply with quote
MazeGen



Joined: 06 Oct 2003
Posts: 975
Location: Czechoslovakia
MazeGen
System86, special prefix is used to access 64-bit operands. The 8-bit and 16-bit operands are addressed the same way like in 32-bit PM.

BTW, there still seems to be a confusion about Long mode. It is generic term - this mode consist of two modes, so in this context, 64-bit mode should be used. Most of the time, we are not talking about compatibility mode.
Post 16 Jun 2008, 07:57
View user's profile Send private message Visit poster's website Reply with quote
sinsi



Joined: 10 Aug 2007
Posts: 693
Location: Adelaide
sinsi
You can't use instructions that access the high byte of a 16-bit register (AH,BH etc.) because of the the REX prefix (for use with R8,R9 etc.) - DB 48h (from memory).
Also, things like AAA,DAA don't work either (generates #UD).
Post 16 Jun 2008, 08:20
View user's profile Send private message Reply with quote
Feryno



Joined: 23 Mar 2005
Posts: 454
Location: Czech republic, Slovak republic
Feryno
Can a 64bit processor run 16 bit programs?

I don't mean Intel itanium 64 bit, I mean x64 platform (AMD64, Intel IA32e)

every 64 bit CPU after reset or power on starts in LEGACY mode and behaves as older CPUs (x86 platform) where you can run real mode (16 bit) and virtual 8086 mode (16 bit)
the new CPUs are able to switch from Legacy mode into new LONG mode
old are able to turn on CR0.PE protected mode + CR0.PG paging, but only new are able to turn on EFER.LME, EFER.LMA (+ CR4.PAE must be enabled also) and thus entering long mode

LONG mode has these submodes:
64 bit submode
COMPATIBILITY submode

compatibility submode has these types:
32 bit compatibility submode
16 bit compatibility submode

There is no possibility to run 16 bit real mode under Long mode (because of CR0.PE=0 disabled protected mode in Real Mode and CR0.PE=1 in long mode). There is no possibility to run virtual 8086 mode under long mode (CPU design doesn't allow it).

as a conclusion:
there is just a possiblitity to run 16 bit compatibility submode of long mode
this mode is not very usefull
32 bit compatibility submode of long mode is very usefull and allows to run applications as in 32 bit LEGACY mode
the 16 bit COMPATIBILITY submode is not very usefull because memory reference doesn't behave as in 16 bit real mode (RM has the formula memory=segment_register*16+offset) and thus memory references are completely different than in real mode
you can easily shut down long mode from 16 bit compatibility submode into real mode by just turning off about 3 various bits in control registers but then you perhaps damage other running processes. You can revert back from real mode into 16 bit compatibility submode by restoring these 3 bits and restoring some registers (fs_base, gs_base, kernel_gs_base, IDT, GDT, some 64 bit general purpose registers, segment registers - their name are selectors in protected mode and long mode etc...)

there is one amazing choice under AMD64 virtualization (such a choice is not possible under intel virtualization) - paged real mode CR0.PE=0 protected mode off and CR0.PG=1 paging on
such a settings CR0.PE=0 and CR0.PG=1 causes an exception when not running under AMD64 virtual machine !!!

well, back to long mode and its submodes...
where are differences? Just in 2 bits in code descriptor... Long bit (CS.L) - bit 21 of dword +4 and Default operand size bit (CS.D) - bit 22. of dword +4
L=0 compatibility submode of long mode
L=1 64 bit submode of long mode

L=0 D=0 16 bit compatibility submode of long mode
L=0 D=1 32 bit compatibility submode of long mode
L=1 D=0 64 bit submode of long mode
L=1 D=1 reserved for feature CPU (128 bit mode? 'extended' 64 bit mode e.g. without limit RIP+dword but with a choice [RIP+qword] and call and jmp instructions without the limit of accessing memory position just dword from current RIP but to access qword distance from current RIP etc?)

if you need to switch 64 bit submode of long mode into 16 bit compatibility submode of long mode, you need to use this code descriptor in global descriptor table

ngdtr:
null selector dq 0
... other selectors...
C16_sel = $ - ngdtr
dq 00009A000000FFFFh ; 16 bit code descriptor
;seg_limit_15_0=FFFF
;base_addr_15_0=0000
;base_addr_23_16=00
;9A=10011010b Present=1, DPL=00b, bit_12=1, bit_11=1, Conforming=0, Readable=1, Accessed=0
;seg_limit_19_6=0
;0=0000b Granularity=0, Default_operand_size=0, Long=0, AVL=0
;the settings required for code segment in real mode is: byte-granular, non-conforming, readable
D16_sel = $ - ngdtr
dq 000092000000FFFFh ; 16 bit data descriptor
;9=1001b Present=1, DPL=00b, bit_12=1
;2=0010b bit_11=0 E=0 W=1 A=0
;this setting is required for data segment in real mode: small, byte-granular, expand-up, writeable

to load this code descriptor, my preferred way is (requires a driver in ring0 of course)
mov ecx,target_SP
mov eax,D16_sel
push rax
push rcx
pushf
mov eax,C16_sel
push rax
mov eax,target_IP ; note the target IP must be in low memory because instruction pointer in 16 bit is limited in its size...
push rax
iretq ; note you need it with REX prefix db 48h, 0CFh. using only iret (db 0CFh) is not sufficient you must use iretq!!!

target_IP:
; this code must be in low memory e.g. copy it there etc...
use16 ; tell the assembler to compile the code here as 16 bit...
; 16 bit code starts here
...

P.S. I posted a lot of info here and I hope I didn't confuse you...

P.S.2 corrected that mistake, thanks to vid (the following post)

P.S. 3 whoops, I found another mistaken letter, the name of this topic should be ...64bit processOr... not '64bit processEr'


Last edited by Feryno on 19 Jun 2008, 16:57; edited 4 times in total
Post 18 Jun 2008, 19:04
View user's profile Send private message Visit poster's website ICQ Number Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Just a note: It's compatibility, not compaCtibility. As in compatible, not as in compact.
Post 18 Jun 2008, 21:26
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You can attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.