16 And 32 Bit

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

16 And 32 Bit

Post by Lprogster »

Hi

...

Thanks,
Lster
Last edited by Lprogster on Tue Oct 23, 2007 10:59 am, edited 1 time in total.
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

There isn't normally any reason to worry about it, but if your code is absolutely speed critical xor ax,ax is slower because the processor has to muck around saving part of the register, whilst modifying another part. According to Intel anyway.

The difference between them is that xor eax,eax will clear the whole of the eax register to zero, whereas xor ax,ax will only clear the lower 16 bits.
Last edited by mathematician on Sun Jun 24, 2007 3:49 am, edited 1 time in total.
User avatar
bluecode
Member
Member
Posts: 202
Joined: Wed Nov 17, 2004 12:00 am
Location: Germany
Contact:

Post by bluecode »

hi,

I think it depends on the mode your in (32bit or 16bit pmode/realmode). In 16bit modes the 32bit instruction needs a prefix byte more (same for 32bit mode and 16bit instruction).
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

Thank you both. That leads me to my final question: which is faster out of these two pieces of code:

...

or

...

I have seen code that do it either way...

Thanks again,
Lster
Last edited by Lprogster on Thu Jun 28, 2007 8:17 am, edited 1 time in total.
User avatar
mathematician
Member
Member
Posts: 437
Joined: Fri Dec 15, 2006 5:26 pm
Location: Church Stretton Uk

Post by mathematician »

The second won't work, because you are trying to copy a 32 bit register into a 16 bit register
jnc100
Member
Member
Posts: 775
Joined: Mon Apr 09, 2007 12:10 pm
Location: London, UK
Contact:

Post by jnc100 »

From a quick test, nasm assembles both mov ds, eax and mov ds, ax to mov ds, ax in both 16 and 32 bit mode. If you look at the Intel manuals,
Intel wrote:MOV Sreg, r/m16
MOV Sreg, r/m64
i.e. there is no instruction to move a 32-bit register to a segment register. The 64 bit one just uses the lower 16 bits.

So the question about speed is just whether loading eax or loading ax is quicker in 32-bit mode.

On the other hand, if you're interested in optimising for space then the following is an interesting disassembly:

Code: Select all

66B81000      mov ax, 0x10
B810000000    mov eax, 0x10
in other words, even with the 0x66 prefix, loading ax uses one byte less space as you only need to specify 16 bits of immediate value.

Regards,
John.
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

Thanks, that is interesting... I never realised Nasm did that...
Lster
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Post by JAAman »

jnc100 wrote:From a quick test, nasm assembles both mov ds, eax and mov ds, ax to mov ds, ax in both 16 and 32 bit mode. If you look at the Intel manuals,
Intel wrote:MOV Sreg, r/m16
MOV Sreg, r/m64
i.e. there is no instruction to move a 32-bit register to a segment register. The 64 bit one just uses the lower 16 bits.

So the question about speed is just whether loading eax or loading ax is quicker in 32-bit mode.
not so...

Code: Select all

mov ax, 0xb800
mov ds, eax
will work exactly the same as:

Code: Select all

mov eax, 0xb800
mov ds, eax
and

Code: Select all

mov ax, 0xb800
mov ds, ax
all three of these have exactly the same affect -- therefore it is not necessary to load the full 32bit eax before using it to load the segment register

the official recommendation from intel is to use:
MOV Sreg, r/m32

the reason for this is that in 32bit mode 32bit is the default size, and processing MOV Sreg, r/m16 requires an extra clock cycle

the r/m32 form isnt mentioned, but its affect is exactly the same as the r/m16 form (and the r/m64 form -- in all forms, only the lower 16bits are used and the rest is ignored

reference 2A: section 3, MOV (page 3-588, paragraph 6 in revision 019US)
Lprogster
Member
Member
Posts: 174
Joined: Tue Nov 14, 2006 11:59 am

Post by Lprogster »

So I should do:

...

That is optimal?

Thanks,
Lster
Last edited by Lprogster on Thu Jun 28, 2007 8:17 am, edited 1 time in total.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Post by bewing »

Depending on the value you are putting in eax, then

Code: Select all

movzx eax, (byte or word) val
is usually the most efficient way to set eax. If you already know that ah or al are 0, or a particular value, then you can sometimes just load ah or al with a byte.
And I think JAAman is probably right, that

Code: Select all

mov ds, eax
is probably best -- IF your assembler converts it properly to machine language -- which is problematic.

Fortunately, setting segment registers is something that should only happen very rarely?
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Post by JAAman »

Lprogster wrote:So I should do:

Code: Select all

mov eax, 1234
mov ds, ax
That is optimal?

Thanks,
Lster
no, optimal would be:

Code: Select all

mov eax, 1234
mov ds, eax                             ; note this line uses the 32bit eax -- no o16 override required
for speed or

Code: Select all

mov ax, 1234
mov ds, eax
for size (save 1 byte over the first encoding)


any assembler should have no problem with mov Sreg, r/m32, and most will add a o16 prefix to a mov Sreg, r/m16 -- which is why the intel manuals specifically recommend using r/m32
Post Reply