Page 1 of 1
16 And 32 Bit
Posted: Sun Jun 24, 2007 3:20 am
by Lprogster
Hi
...
Thanks,
Lster
Posted: Sun Jun 24, 2007 3:47 am
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.
Posted: Sun Jun 24, 2007 3:49 am
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).
Posted: Sun Jun 24, 2007 4:09 am
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
Posted: Sun Jun 24, 2007 4:20 am
by mathematician
The second won't work, because you are trying to copy a 32 bit register into a 16 bit register
Posted: Sun Jun 24, 2007 4:32 am
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.
Posted: Sun Jun 24, 2007 4:42 am
by Lprogster
Thanks, that is interesting... I never realised Nasm did that...
Lster
Posted: Sun Jun 24, 2007 8:01 am
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...
will work exactly the same as:
and
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)
Posted: Sun Jun 24, 2007 10:08 am
by Lprogster
So I should do:
...
That is optimal?
Thanks,
Lster
Posted: Sun Jun 24, 2007 10:47 pm
by bewing
Depending on the value you are putting in eax, then
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
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?
Posted: Mon Jun 25, 2007 8:10 am
by JAAman
Lprogster wrote:So I should do:
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
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