Re: NASM 0.98.39 vs. NASM 2.03.01 disassembly



"Frank Kotler" <fbkotler@xxxxxxxxxxx> wrote in message
news:g8d9fm$pfq$1@xxxxxxxxxxx
Rod Pemberton wrote:
"Frank Kotler" <fbkotler@xxxxxxxxxxx> wrote in message
news:g8an22$v6v$1@xxxxxxxxxxx
Interesting. What would be the "meaning" of a (16-bit!) selector in a
32-bit reg?

Is this a trick question?

Not intended to be.

OK. The meaning of a 16-bit selector in a 32-bit reg is the same as the
meaning
of a 16-bit selector in a 16-bit reg... (How was that not a trick question
again?)

If the upper bits are "garbage", it won't work?

Are you implying that 16-bit selectors in 32-bit mode as implemented
currently don't actually work?

I certainly didn't intend to imply that!

Then, it must've been a trick question... since there is no difference in
meaning, usage, or implementation of a 16-bit selector in a 32-bit reg,
AFAICT, and you didn't intend to imply that.

Let me try this again... Assume 32-bit code...

You write:

lsl eax, ebx

I write:

lsl eax, bx

What's the difference?

One is a valid 32-bit instruction. One isn't AFAICT (even with
overrides...).

Same machine code,

Where do you get this?

I posted the encoding information from _four_ respectable manuals. LSL
r32,r16 isn't present anywhere. (I granted you that interpretation for one
manual, remember?) At a minimum, "lsl eax,bx" would require an override for
32-bit code to generate "bx" instead of "ebx" (but that would also require a
change to "eax"), i.e., the code must be different.

(If you don't agree to this interpretation, then Ndisasm's decoding of
override prefixes is broken for all instructions other than lsl and lar.
Because, that's how they all work.)

This looks
like a change from m32 to m16 somewhere between 2003 and 2006.

Little endian with 16-bit selectors. Basically, irrelevant if the cpu
ignores retrieving the upper 16-bits of a 32-bit value from memory...

... Ah, but here it *does* make a difference if the instruction reads 32
bits and discards 16!

Why? It doesn't make a difference under normal circumstances. It only
exhibits a problem under special circumstances: misaligned memory read split
across a boundary of unmapped memory.

... Ah, but here it *does* make a difference if the instruction reads 32
bits and discards 16! Only if the 16 bits in question is the last 16
bits of readable memory, to be sure...

What does "little endian" mean to you?

In memory, little endian 16-bit value 0x1100 is stored (with 0x00 byte at
the lower address):

00 11

In memory, little endian 32-bit value 0x33221100 is stored:

00 11 22 33

I.e., a valid read (no faults...) from the stored address of 16-bits and of
32-bits which discards the upper 16-bits will both have the lower 16-bits be
0x1100.

This is the experiment that Phil
proposed. On the only processor I've tested it on - P4 - it definitely
reads only 16-bits.

How does one align a 32-bit general purpose register on an unmapped memory
boundary to generate an alignment trap to determine if half of or the whole
of a 32-bit register is used? (This is a trick question.)

or did they fix an error in the manual?

No, I don't believe so.

If I see results of an *experiment* that shows lar/lsl reading 32 bits
with some CPU, I'll agree with you.

That's an invalid conclusion. The conclusion only applies to the memory
operand as source, not either of the register operands (destination or
source). The size of the memory read has no effect on the size of the
register used. You can see that LSL can use 32-bit registers for _both_,
while accessing memory as 16-bits for the second, according to one of the
manuals. Look:

0F 03 /r LSL r32, r32/m16

I would "expect" the source operand to be 16-bits,

ABSOLUTELY NOT! If the cpu is in 32-bit mode and the source operand is
a
register, the register size is either 32-bits or 8-bits.

regardless of the
processor mode or size of the destination register, a selector being 16
bits.

In 16-bit mode, you have two register sizes: 8-bit and 16-bit. In
32-bit
mode, you have two register sizes: 8-bit and 32-bit.

Are you implying that:

lsl ax, bx

won't work in 32-bit code?

No, I'm not. IMO, you seem to be confusing/merging the encoding/decoding
and instruction operation.

The question is either:

"Is lsl ax,bx encoded as 16-bits, then executed as 32-bits?"

*OR*

"Is lsl ax,bx encoded in 32-bit mixed mode and executed as 32-bits?"

If "lsl ax, bx" was encoded as 16-bits, and then executed in 32-bit mode,
it'll be executed as "lsl eax, ebx". It'll work. But, it won't work as
coded. The fact that this instruction may have the identical operational
result is irrelevant. If decoded as 32-bits, it should decode as "lsl eax,
ebx" not "lsl eax, bx".

If "lsl ax, bx" was encoded as 32-bits in mixed mode (i.e., with override),
and then executed in 32-bit mixed mode, it'll be executed as the equivalent
16-bit code due to the override.

As Phil suggests, we could conduct the experiment. I have done so,
both loading upper bits of ebx with garbage, and putting a 16-bit
variable in the last two bytes of valid memory. I conclude that the
source operand is 16 bits...

I think that's a wrong conclusion. You can conclude that only 16-bits
of
the source operand are used as a selector. But, you can't determine
what
size 32-bits or 16-bits was read in order to obtain the 16-bit selector.

I certainly can! If it were reading 32 bits, it'd segfault!

That needs to be qualified: "If it were reading 32 bits" [of memory, under
special conditions] "it'd segfault!" So, no, you can't legitimately make
that claim since we're also dealing with register reads not just memory
reads. You're willfully ignoring a register source operand and assuming
that what's true for memory source operand size is also true for the
register source operand size.

My whole point is how do you get "bx", a 16-bit register, instead of
"ebx"
for an instruction decode which can only return an 8-bit or 32-bit
register?

You got me!

Why are you surprised? That is what Ndisasm is doing to lsl, and lar
decodes... It's emitting a 16-bit register for a 32-bit one, erroneously.

What CPU would that be???

AFAIK, we've been talking about Ndisasm instruction decoding, not CPU's in
general nor a specific one.


Rod Pemberton

.



Relevant Pages

  • Re: can somebody help me with the problem with tasm models
    ... When Intel created the x86 originally, ... registers...now, when addressing memory with something like "", this ... valid...the rest aren't yet wired in and are ignored in memory addressing ... "offset" register, this would give a 20-bit address...if, in time, they ...
    (alt.lang.asm)
  • Re: Calculating checksums...
    ... - it's a word memory reference using a register address ... lods - it's the lods instruction ... parens are a memory reference. ... programming and why, with the end of the 68k, teaching assembly ...
    (alt.lang.asm)
  • Re: Volatile variables
    ... Memory barriers come in four "memory" flavors -- ... one needs only a single "store/load" barrier between the write to ... the command register and the read from the status register. ... does a full CPU pipeline flush and empties the write aggregation ...
    (comp.lang.c)
  • Re: [linux-usb-devel] Re: serious 2.6 bug in USB subsystem?
    ... I'll respond to your concerns about my OHCI changes later on. ... wanted to make progress on the BTC HID issue first so we have the full ... looky here what you get when you interpret the memory at address ... or ControlListFilled bit of the HcCommandStatus register. ...
    (Linux-Kernel)
  • Re: again, external symbols in hla
    ... of a register, then list is the symbolic name of a memory location. ... mov ebx, list ... mov eax, list + 8 ...
    (alt.lang.asm)