Re: NASM 0.98.39 vs. NASM 2.03.01 disassembly



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.

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!

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

You write:

lsl eax, ebx

I write:

lsl eax, bx

What's the difference? Same machine code, so obviously same behavior. (FWIW, ald disassembles this a "ebx" - like Ndisasm 0.98.39 - objdump and gdb disassemble it as "%bx"...) You can say it's "reading" all of ebx, and discarding the high 16 bits if you want. No difference...

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! Only if the 16 bits in question is the last 16 bits of readable memory, to be sure... This is the experiment that Phil proposed. On the only processor I've tested it on - P4 - it definitely reads only 16-bits.

Did the
behavior of the processor change,

According to the manual for memory source operands, yes.

Right.

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. Until then, I suspect they fixed an error in the manual.

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.

ABSOLUTELY NOT!

Are you implying that:

lsl ax, bx

won't work in 32-bit code? (As Wolfgang points out, it's probably not useful).

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!

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! What CPU would that be???

Best,
Frank

(ugly, but I believe it proves what I claim it proves...)

global _start

section .text

_start:
nop
mov ebx, -1
mov bx, ds
lsl eax, bx
lsl eax, ebx

lsl eax, [last_word]
mov eax, [last_word] ; segfault! (but not with ax)

mov eax, 1
int 80h

align 16
code_size equ $ - $$

section .data
times 4096 - code_size + 20h - 2 db 0
last_word dw 2Bh
.



Relevant Pages