Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What should the correct syntax for LSL be?

38 views
Skip to first unread message

spam...@crayne.org

unread,
May 12, 2006, 1:10:33 AM5/12/06
to
I have run across an interesting problem when running various tests on
HLA. The LSL instruction is specified in the Intel documentation as
follows:

0F 03 /r LSL r16,r/m16 Load: r16 ← segment limit, selector r/m16.
0F 03 /r LSL r32,r/m32 Load: r32 ← segment limit, selector r/m32).

Now the Intel documentation isn't very clear on this point, but I get
the impression that an assembler does *not* allow either syntax to be
used, but rather lets you specify the 16-bit version in a 16-bit
segment and the 32-bit version in a 32-bit segment (I'm guessing here,
but that's what the documentation seems to imply). Obviously, the
opcodes are exactly the same, so I'm assuming this is how the CPU
differentiates them.

The main reason I'm asking is because MASM only allows the 32-bit
syntax whereas FASM allows only the 16-bit syntax. I suspect that this
is a defect in FASM, but I'm wanting to verify this before deciding
what to do with HLA's code generation algorithm.

Thanks,
Randy Hyde

spam...@crayne.org

unread,
May 12, 2006, 2:44:03 AM5/12/06
to


The AMD doc is somewhat clearer, but says something rather different.
It says that the size of the segment specified in the 16 bit second
parameter is stored in the first parameter, in either 64, 32 or 16 bit
format, truncated as necessary. I'd say that that both address and
operand size overrides (and REX's) are valid, and do the obvious thing.

Of course the last time I coded an LSL was in straight 16 bit code...

Herbert Kleebauer

unread,
May 12, 2006, 5:47:26 AM5/12/06
to
"rand...@earthlink.net" wrote:
>
> I have run across an interesting problem when running various tests on
> HLA. The LSL instruction is specified in the Intel documentation as
> follows:
>
> 0F 03 /r LSL r16,r/m16 Load: r16 ← segment limit, selector r/m16.
> 0F 03 /r LSL r32,r/m32 Load: r32 ← segment limit, selector r/m32).
>
> Now the Intel documentation isn't very clear on this point, but I get
> the impression that an assembler does *not* allow either syntax to be
> used, but rather lets you specify the 16-bit version in a 16-bit
> segment and the 32-bit version in a 32-bit segment (I'm guessing here,
> but that's what the documentation seems to imply). Obviously, the
> opcodes are exactly the same, so I'm assuming this is how the CPU
> differentiates them.

The documentation says:

When the operand size is 32 bits, the 32-bit byte limit is stored in the
destination operand. When the operand size is 16 bits, a valid 32-bit
limit is computed; however, the upper 16 bits are truncated and only
the lower 16 bits are loaded into the destination operand.


Therfore I use:
seg16
00000000: 0f 03 c2 ldsl.w r0,r1
00000003: 66 0f 03 c2 ldsl.l r0,r1

seg32
00000007: 66 0f 03 c2 ldsl.w r0,r1
0000000b: 0f 03 c2 ldsl.l r0,r1

spam...@crayne.org

unread,
May 15, 2006, 2:56:44 PM5/15/06
to

Herbert Kleebauer wrote:
>
> The documentation says:
>
> When the operand size is 32 bits, the 32-bit byte limit is stored in the
> destination operand. When the operand size is 16 bits, a valid 32-bit
> limit is computed; however, the upper 16 bits are truncated and only
> the lower 16 bits are loaded into the destination operand.
>
>
> Therfore I use:
> seg16
> 00000000: 0f 03 c2 ldsl.w r0,r1
> 00000003: 66 0f 03 c2 ldsl.l r0,r1
>
> seg32
> 00000007: 66 0f 03 c2 ldsl.w r0,r1
> 0000000b: 0f 03 c2 ldsl.l r0,r1


I notice, however, that you've encoded a $66 size prefix into the seg32
section. The Intel documentation doesn't mention this. And this is
exactly why I was asking the question -- there is no way to
differentiate the two based on the opcode. Either the differentiation
is done by the segment size (only), or the Intel documentation is
wrong. That's what I'm trying to figure out.

Herbert Kleebauer

unread,
May 15, 2006, 5:17:00 PM5/15/06
to
"rand...@earthlink.net" wrote:
> Herbert Kleebauer wrote:

> > The documentation says:
> >
> > When the operand size is 32 bits, the 32-bit byte limit is stored in the
> > destination operand. When the operand size is 16 bits, a valid 32-bit
> > limit is computed; however, the upper 16 bits are truncated and only
> > the lower 16 bits are loaded into the destination operand.
> >
> >
> > Therfore I use:
> > seg16
> > 00000000: 0f 03 c2 ldsl.w r0,r1
> > 00000003: 66 0f 03 c2 ldsl.l r0,r1
> >
> > seg32
> > 00000007: 66 0f 03 c2 ldsl.w r0,r1
> > 0000000b: 0f 03 c2 ldsl.l r0,r1
>
> I notice, however, that you've encoded a $66 size prefix into the seg32
> section. The Intel documentation doesn't mention this.

_ Prefixes -- one or more bytes preceding an instruction that modify the
operation of the instruction. The following types of prefixes can be
used by applications programs:

2. Address size -- switches between 32-bit and 16-bit address
generation.

3. Operand size -- switches between 32-bit and 16-bit operands.


> And this is
> exactly why I was asking the question -- there is no way to
> differentiate the two based on the opcode. Either the differentiation
> is done by the segment size (only), or the Intel documentation is
> wrong. That's what I'm trying to figure out.

I don't understand what you want to say. I don't see any difference
in ldsl and for example the add instruction. If you want a 32 bit
operation in a 16 bit segment or a 16 bit operation in a 32 bit
segment, then you have to prefix the instruction by 66.

seg16

00000000: 0f 03 c2 ldsl.w r0,r1
00000003: 66 0f 03 c2 ldsl.l r0,r1

00000007: 01 c2 add.w r0,r1
00000009: 66 01 c2 add.l r0,r1


seg32

0000000c: 66 0f 03 c2 ldsl.w r0,r1
00000010: 0f 03 c2 ldsl.l r0,r1

00000013: 66 01 c2 add.w r0,r1
00000016: 01 c2 add.l r0,r1


And for an address size switch you have to use 67:


seg16

00000000: 0f 03 07 ldsl.w r0,(r3.w)
00000003: 67 0f 03 03 ldsl.w r0,(r3.l)
00000007: 66 0f 03 07 ldsl.l r0,(r3.w)
0000000b: 67 66 0f 03 03 ldsl.l r0,(r3.l)


seg32

00000010: 67 66 0f 03 07 ldsl.w r0,(r3.w)
00000015: 66 0f 03 03 ldsl.w r0,(r3.l)
00000019: 67 0f 03 07 ldsl.l r0,(r3.w)
0000001d: 0f 03 03 ldsl.l r0,(r3.l)

Herbert Kleebauer

unread,
May 15, 2006, 5:40:07 PM5/15/06
to
Herbert Kleebauer wrote:


Sorry, but it seems my assembler has got an Intel virus and
now also mixes up source and destination (never used this
instruction) but at least the disassembler does it the correct
way.


> seg16
>
> 00000000: 0f 03 07 ldsl.w r0,(r3.w)
> 00000003: 67 0f 03 03 ldsl.w r0,(r3.l)
> 00000007: 66 0f 03 07 ldsl.l r0,(r3.w)
> 0000000b: 67 66 0f 03 03 ldsl.l r0,(r3.l)

00000100 ldsl.w (r3.w),r0 (0f 03 07)
00000103 ldsl.w (r3),r0 (67 0f 03 03)
00000107 ldsl.l (r3.w),r0 (66 0f 03 07)
0000010b ldsl.l (r3),r0 (67 66 0f 03 03)

Charles A. Crayne

unread,
May 15, 2006, 5:21:50 PM5/15/06
to
On 15 May 2006 11:56:44 -0700
"rand...@earthlink.net" <spam...@crayne.org> wrote:

:Either the differentiation


:is done by the segment size (only), or the Intel documentation is
:wrong.

False dichotomy.

The default operand-size and address-size attributes are determined by
the D bit in the code segment descriptor, but may be modified for any
given instruction by use of the appropriate instruction prefixes. This
rule is so basic to the architecture that it would be massively redundant
to repeat it the individual instruction descriptions.

-- Chuck

spam...@crayne.org

unread,
May 15, 2006, 8:13:38 PM5/15/06
to

Herbert Kleebauer wrote:
>
> I don't understand what you want to say. I don't see any difference
> in ldsl and for example the add instruction. If you want a 32 bit
> operation in a 16 bit segment or a 16 bit operation in a 32 bit
> segment, then you have to prefix the instruction by 66.

I don't understand either. That's why I'm asking. The Intel
documentation isn't clear about this. Maybe I'm just expecting the
documentation to be a little more clear about the differences between
the opcodes in 32-bit mode.

Well, I guess the problem that I am having is that MASM refuses to
compile the 16-bit version in 32-bit mode and FASM refuses to compile
the 32-bit version in 32-bit mode, but both generate exactly the same
opcode sequence (one with 32-bit operands, one with 16-bit operands).
Clearly, both assemblers are broken (though FASM moreso than MASM on
this point).

One could argue that MASM's error is the least obtrusive as as 16-bit
LSL is probably useless for all practical purposes in 32-bit mode.
Clearly FASM's error is a defect that ought to be corrected.

Charles A. Crayne

unread,
May 15, 2006, 11:08:06 PM5/15/06
to
On 15 May 2006 17:13:38 -0700
"rand...@earthlink.net" <spam...@crayne.org> wrote:

:Clearly FASM's error is a defect that ought to be corrected.

Not so clear, actually.

In testing with FASM under Linux, I got the following results:
0F 03 C3 lsl eax,bx ;16-bit selector in 16-bit register
0F 03 03 lsl eax,[ebx];32-bit register -> 16-bit selector
67 0F 03 07 lsl eax,[bx] ;16-bit register -> 16-bit selector
<error> lsl eax,ebx ;16-bit selector in 32-bit register

Note that the assembled code is correct in all cases, although a
disassembler might be show case 1 as lsl eax,ebx.

Presumably, FASM's refusal to accept the last case is because a selector
is always 16 bits.

-- Chuck

Frank Kotler

unread,
May 16, 2006, 2:00:18 AM5/16/06
to

That makes sense. Nasm does it differently... in the reg, reg forms, the
size of the registers must match - "lsl eax, bx" reports an "invalid
combination of opcode and operands".

Seems to me that an assembler ought to accept *either* "lsl eax, ebx" or
"lsl eax, bx", emitting the same opcode - no override - for either case.
Since, as you say, a selector is always 16 bits, it's the same
operation. Much like "mov ds, ax" vs "mov ds, eax" (in 32-bit code) -
some assemblers (perhaps only Masm, at this point) require the latter
syntax to avoid emitting the override... but it's the same instruction
in either case - the override (if any) is ignored...

Pity Nasm and Fasm didn't do it the same...

Best,
Frank

spam...@crayne.org

unread,
May 16, 2006, 12:01:22 PM5/16/06
to

Charles A. Crayne wrote:
> On 15 May 2006 17:13:38 -0700
> "rand...@earthlink.net" <spam...@crayne.org> wrote:
>
> :Clearly FASM's error is a defect that ought to be corrected.
>
> Not so clear, actually.
>
> In testing with FASM under Linux, I got the following results:
> 0F 03 C3 lsl eax,bx ;16-bit selector in 16-bit register
> 0F 03 03 lsl eax,[ebx];32-bit register -> 16-bit selector
> 67 0F 03 07 lsl eax,[bx] ;16-bit register -> 16-bit selector
> <error> lsl eax,ebx ;16-bit selector in 32-bit register

You missed,
LSL ax, bx

Which also produces 0F 03 C3.

And then there's MASM, which only accepts "lsl eax, ebx" (of the
register forms) and also produces 0F 03 C3 for the result.

The Intel documentation says the following:

0F 03 /r LSL r16, r16/m16 Valid Valid Load: r16 ← segment limit,
selector r16/m16.
0F 03 /r LSL r32, r32/m161 Valid Valid Load: r32 ← segment limit,
selector r32/m16.

Which suggests that (reg16, reg16) and (reg32, reg32) are both legal
forms. Though you could make a logical argument for a (reg32, reg16)
form, the Intel documentation says nothing about this.

That's why I'm asking for clarification of the Intel documentation.
Clearly, someone is doing this wrong here (and probably both
assemblers).


Cheers,
Randy Hyde

Frank Kotler

unread,
May 16, 2006, 2:59:11 PM5/16/06
to
Herbert Kleebauer wrote:
> Frank Kotler wrote:

>
>>Charles A. Crayne wrote:
>
>
>>>In testing with FASM under Linux, I got the following results:
>>>0F 03 C3 lsl eax,bx ;16-bit selector in 16-bit register
>>>0F 03 03 lsl eax,[ebx];32-bit register -> 16-bit selector
>>>67 0F 03 07 lsl eax,[bx] ;16-bit register -> 16-bit selector
>>><error> lsl eax,ebx ;16-bit selector in 32-bit register
>>>
>>>Note that the assembled code is correct in all cases, although a
>>>disassembler might be show case 1 as lsl eax,ebx.
>>>
>>>Presumably, FASM's refusal to accept the last case is because a selector
>>>is always 16 bits.
>>
>>That makes sense. Nasm does it differently... in the reg, reg forms, the
>>size of the registers must match - "lsl eax, bx" reports an "invalid
>>combination of opcode and operands".
>>
>>Seems to me that an assembler ought to accept *either* "lsl eax, ebx" or
>>"lsl eax, bx", emitting the same opcode - no override - for either case.
>>Since, as you say, a selector is always 16 bits, it's the same
>>operation. Much like "mov ds, ax" vs "mov ds, eax" (in 32-bit code) -
>>some assemblers (perhaps only Masm, at this point) require the latter
>>syntax to avoid emitting the override... but it's the same instruction
>>in either case - the override (if any) is ignored...
>
>
> In the case of "lsl" the operandsize prefix wouldn't be ignored,
> It would change the size of the destination and not the size of
> the source register (which holds the 16 bit selector).

Right. Using a 16-bit destination isn't going to be that helpful, even
in a 16-bit segment - the actual limit is going to be 32-bits (all bets
are off on 64-bit machines - I have no clue). Maybe a truncated limit
would be some use - mostly, I think we're going to want the whole 32-bit
result... so we'd want the override in 16-bit code, usually.

The source is always 16-bits - Nasm makes us *say* "lsl eax, ebx", but
only bx is used (experimentation shows that garbage in the high word of
ebx makes no difference). I haven't done an experiment on the reg, mem
form, but surely it only reads 16-bits, regardless of prefix (???
assumption is the mother of fuckup, I suppose...).

Honestly, I'd say that Fasm gets it right - "lsl eax, bx". Nasm insists
on "lsl eax, ebx", which *looks* like properly matched operands, but is
misleading, since src is always 16 bits... Ideally, I'd (LuxAsm?) accept
either way of "saying" the source, much as you'd accept either "mov ds,
ax" or "mov ds, eax" and generate the same sequence (no override).

I guess Randy's original question (?) was whether "lsl ax, bx" is valid
(in 32-bit code... do we care about 16-bit?). Apparently, yes, but
returns a "truncated" limit in ebx - upper word untouched. Not too
useful, but apparently valid...

Ideal syntax would be "lsl ax, bx", not "lsl (bx, ax);"
, of course! :)

Best,
Frank

spam...@crayne.org

unread,
May 16, 2006, 3:47:13 PM5/16/06
to

Frank Kotler wrote:
>
> Right. Using a 16-bit destination isn't going to be that helpful, even
> in a 16-bit segment - the actual limit is going to be 32-bits (all bets
> are off on 64-bit machines - I have no clue).

>From the Intel Documentation:

REX.W + 0F 03 /r LSL r64, r32/m161 Valid Valid Load: r64 ← segment
limit,
selector r32/m16

IOW, you're getting a 64-bit limit.

> Maybe a truncated limit
> would be some use - mostly, I think we're going to want the whole 32-bit
> result... so we'd want the override in 16-bit code, usually.

AFAICT, the 16-bit version in 32-bit mode is useless. This is probably
why MASM doesn't support it at all.

>
> The source is always 16-bits - Nasm makes us *say* "lsl eax, ebx", but
> only bx is used (experimentation shows that garbage in the high word of
> ebx makes no difference). I haven't done an experiment on the reg, mem
> form, but surely it only reads 16-bits, regardless of prefix (???
> assumption is the mother of fuckup, I suppose...).

>From the Intel documentation:

0F 03 /r LSL r16, r16/m16 Valid Valid Load: r16 ← segment limit,
selector r16/m16.

0F 03 /r LSL r32, r32/m16[1] Valid Valid Load: r32 ← segment limit,
selector r32/m16.

[1] For all loads (regardless of destination sizing), only bits 16-0
are used. Other bits are ignored.

IOW, memory operands are always 16 bits. Even with the register is 32
bits, only 16 bits are read, according to Intel. So yes, "lsl eax, bx"
would seem to make more sense, but the Intel syntax calls for "lsl eax,
ebx". So in that respect NASM is right. We could easily argue that
Intel is wrong (they are on many other mnemonics and instruction
syntaxes); but that's a different issue.

>
> Honestly, I'd say that Fasm gets it right - "lsl eax, bx". Nasm insists
> on "lsl eax, ebx", which *looks* like properly matched operands, but is
> misleading, since src is always 16 bits...

NASM didn't get it wrong, Intel did. NASM is just doing what Intel
called for.


> Ideally, I'd (LuxAsm?) accept
> either way of "saying" the source, much as you'd accept either "mov ds,
> ax" or "mov ds, eax" and generate the same sequence (no override).
>
> I guess Randy's original question (?) was whether "lsl ax, bx" is valid
> (in 32-bit code... do we care about 16-bit?). Apparently, yes, but
> returns a "truncated" limit in ebx - upper word untouched. Not too
> useful, but apparently valid...

Actually, my question was about the prefix bytes. A 16-bit LSL is
definitely valid, though the results won't make much sense.
Cheers,
Randy Hyde

Charles A. Crayne

unread,
May 16, 2006, 10:01:56 PM5/16/06
to
On 16 May 2006 09:01:22 -0700
"rand...@earthlink.net" <spam...@crayne.org> wrote:

:You missed,
: LSL ax, bx

Here is an expanded list:

0F 03 C3 lsl eax,bx

0F 03 03 lsl eax,[ebx]

67 0F 03 07 lsl eax,[bx]

<error> lsl eax,ebx
0F 03 05 00 00 00 00 lsl eax,[selector16]
<error> lsl eax,[selector32]
66 0F 03 C3 lsl ax,bx
66 0F 03 03 lsl ax,[ebx]
67 66 0F 03 07 lsl ax,[bx]
<error> lsl ax,ebx
66 0F 03 05 00 00 00 00 lsl ax,[selector16]
<error> lsl ax,[selector32]

Please note that FASM is consistent in rejecting any attempt to specify a
32-bit selector value, which is reasonable, since selectors are always 16
bits.

:Clearly, someone is doing this wrong here (and probably both
:assemblers).

It's not a question of right or wrong, since both assemblers produce
correct code, but rather of programming style. You chose not to use strict
Intel syntax in HLA, so why does it bother you that NASM and FASM share
this trait?

-- Chuck

spam...@crayne.org

unread,
May 16, 2006, 11:46:02 PM5/16/06
to

Charles A. Crayne wrote:
>
> Please note that FASM is consistent in rejecting any attempt to specify a
> 32-bit selector value, which is reasonable, since selectors are always 16
> bits.

Contrary to Intel's semantics.

>
> :Clearly, someone is doing this wrong here (and probably both
> :assemblers).
>
> It's not a question of right or wrong, since both assemblers produce
> correct code, but rather of programming style. You chose not to use strict
> Intel syntax in HLA, so why does it bother you that NASM and FASM share
> this trait?

Actually, it's MASM and FASM, not NASM that differ from Intel's syntax.
NASM works just the way Intel says it should. As for HLA, it provides
extensions, but I've generally supported the operands exactly the way
Intel suggests that they should be supported. For example, the LSL
instruction accepts two 32-bit registers. I am going to, however, drop
support for the 16-bit register form as that's a 16-bit-ism that has
absolutely no use in flat-model 32-bit programs (then again, one could
argue that there is little use for the LSL instruction in flat model
code, but that's a different argument).
Cheers,
Randy Hyde

Charles A. Crayne

unread,
May 17, 2006, 5:13:40 PM5/17/06
to
On 16 May 2006 20:46:02 -0700
"rand...@earthlink.net" <spam...@crayne.org> wrote:

:Contrary to Intel's semantics.

"Still, a man hears what he wants to hear
And disregards the rest."

[Simon and Garfunkel]

Frank Kotler

unread,
May 17, 2006, 5:41:42 PM5/17/06
to
rand...@earthlink.net wrote:
> Frank Kotler wrote:
>
>>Right. Using a 16-bit destination isn't going to be that helpful, even
>>in a 16-bit segment - the actual limit is going to be 32-bits (all bets
>>are off on 64-bit machines - I have no clue).
>
>
>>From the Intel Documentation:
>
> REX.W + 0F 03 /r LSL r64, r32/m161 Valid Valid Load: r64 <- segment

> limit,
> selector r32/m16
>
> IOW, you're getting a 64-bit limit.

Okay... that's "as expected"... surprisingly, in 64-bit :)

>>Maybe a truncated limit
>>would be some use - mostly, I think we're going to want the whole 32-bit
>>result... so we'd want the override in 16-bit code, usually.
>
>
> AFAICT, the 16-bit version in 32-bit mode is useless. This is probably
> why MASM doesn't support it at all.

Not very useful in 16-bit mode either - the limit is still 32 bits.
But... not the assemblers job to decide what's "useful", IMHO. If the
instruction is "valid", a "good" assembler ought to generate it, if
asked. (hopefully *only* when asked :)

....


> NASM didn't get it wrong, Intel did. NASM is just doing what Intel
> called for.

You've got a cc on this, I think. For the rest of us:

<https://sourceforge.net/tracker/index.php?func=detail&aid=1490407&group_id=6208&atid=106208>

Nasm64developer has submitted a patch to "correct" Nasm's behavior. With
this patch applied, "lsl eax, bx" assembles correctly, but "lsl eax,
ebx" is an error... breaking existing code... if any...

I'm still inclined to think that accepting both would be ideal (I'll
take a look to see if I can figure out how to do that, having been given
a clue...)

I'm not sure what Fasm or HLA2 do with:

mov ds, ax

(in 32-bit code) It *looks* like it needs an override, but the override
has no effect. The Intel Manual (as quoted to me, as usual) says "most
assemblers" require "mov ds, eax" to avoid generating the override. Masm
generates the override on "mov ds, ax", Tasm, Gas, and now Nasm, do not.
Maybe they should spell it "MoSt" :)

This seems to me like a similar situation. Nasm64developer observes that
the same situation exists on "lar"...

Best,
Frank

Philippe Auphelle

unread,
May 29, 2006, 9:44:03 AM5/29/06
to
Randy,

> Well, I guess the problem that I am having is that MASM refuses to
> compile the 16-bit version in 32-bit mode and FASM refuses to compile
> the 32-bit version in 32-bit mode, but both generate exactly the same
> opcode sequence (one with 32-bit operands, one with 16-bit operands).
> Clearly, both assemblers are broken (though FASM moreso than MASM on
> this point).

Doesn't look to me that MASM refuses to compile the 16 bit version in 32
bit mode (nor the 32 bit version in the 16 bit mode, BTW): it generates
the mode override prefix in a rather predictable way, doesn't it?

00000000 InitCode32 SEGMENT BYTE PUBLIC USE32 'INITCODE'

00000000 66| 50 PUSH AX
00000002 50 PUSH EAX
00000003 0F 03 C3 LSL EAX,EBX
00000006 66| 0F 03 C3 LSL AX,BX
0000000A 66| 0F 03 C7 LSL AX,DI
0000000E 66| 0F 03 C8 LSL CX,AX
00000012 0F 03 C8 LSL ECX,EAX
; But it doesn't want reg size mixes.
LSL EAX,BX
..\Int13h.asm(1351) : error A2022: instruction operands must be the same
size
LSL AX,EBX
..\Int13h.asm(1352) : error A2022: instruction operands must be the same
size

002B InitCode32 ENDS


Microsoft (R) Macro Assembler Version 7.00.9466 05/29/06 15:32:11
Page 32 - 1
0000 InitCode16 SEGMENT BYTE PUBLIC USE16 'INITCODE'

0000 50 PUSH AX
0001 66| 50 PUSH EAX
0003 66| 0F 03 C3 LSL EAX,EBX
0007 0F 03 C3 LSL AX,BX
000A 0F 03 C7 LSL AX,DI
000D 0F 03 C8 LSL CX,AX
0010 66| 0F 03 C8 LSL ECX,EAX
LSL EAX,BX
; But it doesn't want reg size mixes.
..\Int13h.asm(1366) : error A2022: instruction operands must be the same
size
LSL AX,EBX
..\Int13h.asm(1367) : error A2022: instruction operands must be the same
size

002A InitCode16 ENDS

0 new messages