Author Topic: Is This a Problem with NASM? Seems to be.  (Read 7701 times)

Offline oldefoxx

  • Jr. Member
  • *
  • Posts: 3
Is This a Problem with NASM? Seems to be.
« on: September 04, 2012, 02:41:33 AM »
I was working with HotBasic, which has its own built-in Assembler.  I found it did not make a distinction between words and dwords, although
it is suppose to.  A number of inquiries through the HotBasic Group finally resulted in a programmer telling me that a mnemonic like movsd
consisted on one byte, and for movsw a prefix of 66h was inserted.  I later confirmed this is true, for the most part.  What varies is if the
instruction defaults to 16 bits, in which case the 66h changes it to 32 bits.  If the default is to 32 bits, the 66h changes it to 16 bits.

Unless you know the default state of an instruction, it's hard to judge if a 66h prefix is needed or not.  You pretty much have to depend on the
Assembler to make the choice for you.  Except with the HotBasic built-in assember, that doesn't handle the problem at all.  You need to find
out somewhere else and come back and do a asm db 66h if needed before the mnemonic.

So , to find out on an instruction by instruction basis, I rigged up a simploe program in HotBasic to use three Assemblers to find out what all
three recommend.  NASM and FASM usually agree, but are 180 degrees out from what MASM32 recommends.  However, MASM32 is told that
it is to use .486, meaning its default is 32 bits, not 16 bits.  At least I think that is why the difference right now.

But I have a case where Nasm apparently makes a serious mistake.  Here is a copy-and-paste from a running instance of my program:

  Enter an 80x86 instruction mnemonic to convert: add eax,1
  ml.exe says "add eax,1" translates to " 83 C0 01 "
  nasm.exe says "add eax,1" translates to " 66 05 01 00 00 00 "
  fasm.exe says "add eax,1" translates to " 66 83 C0 01 "

Note that ml.exe (Masm32) and Fasm only differ by whether the 66h prefix byte is required.  The rest of the instruction is a match.  But
Nasm does something quite different, and according to one follower of my post on the PureBasic forums, the instruction of "66 05 01 00 00 00" is invalid, causes an error on execution.  Thought I would pass this along. 

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is This a Problem with NASM? Seems to be.
« Reply #1 on: September 04, 2012, 03:46:54 AM »
We will fix Nasm so it agrees with HotBASIC immediately! :)

Seriously, oldefoxx, think about what you're saying. Nasm (or Fasm or Masm) should get its advice from a BASIC forum? Get real.

I wrote up an extensive reply to your earlier post, explaining the situation. Unfortunately, I dropped it on the floor before posting (my fault, not the Forum's). I found that Keith had posted even better advice: Read the friendly Intel manual!

Does the phrase "burnt toast" mean anything to you? Go back to that viewpoint and you'll be ahead of the game.

(for other readers: http://www.programmersheaven.com/mb/basic/429271/429271/hotbasic-compilers-and-inline-assembly/ )

Best,
Frank


Offline cm

  • Jr. Member
  • *
  • Posts: 65
Re: Is This a Problem with NASM? Seems to be.
« Reply #2 on: September 04, 2012, 04:46:04 AM »
Presumably, Frank didn't bother replying to this point in detail, but let's correct it anyway.

But I have a case where Nasm apparently makes a serious mistake.  Here is a copy-and-paste from a running instance of my program:

  Enter an 80x86 instruction mnemonic to convert: add eax,1
  ml.exe says "add eax,1" translates to " 83 C0 01 "
  nasm.exe says "add eax,1" translates to " 66 05 01 00 00 00 "
  fasm.exe says "add eax,1" translates to " 66 83 C0 01 "

Note that ml.exe (Masm32) and Fasm only differ by whether the 66h prefix byte is required.

That is, by whether they assemble the code for a 32-bit or a 16-bit code segment.

Quote
The rest of the instruction is a match.  But
Nasm does something quite different, and according to one follower of my post on the PureBasic forums, the instruction of "66 05 01 00 00 00" is invalid, causes an error on execution.  Thought I would pass this along.

Code: [Select]
D:\>debug
-e 100 66 05 01 00 00 00
-r
AX=0000 BX=0000 CX=0000 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=13A4 ES=13A4 SS=13A4 CS=13A4 IP=0100 NV UP EI PL ZR NA PE NC
13A4:0100 660501000000      add     eax, 00000001
-t
AX=0001 BX=0000 CX=0000 DX=0000 SP=FFFE BP=0000 SI=0000 DI=0000
DS=13A4 ES=13A4 SS=13A4 CS=13A4 IP=0106 NV UP EI PL NZ NA PO NC
13A4:0106 90                nop
-q

My debugger (which arguably could be faulty) disassembles 66 05 01 00 00 00 in a 16-bit code segment as "add eax, 00000001", and according to my AMD K9-generation processor that instruction is valid, executing that sequence in such a segment in V86M does in fact seem to act like an add instruction with source operand 1 and destination operand eax.

Resolution of this controversy would require the existence of some definitive kind of documentation on the expected and required behaviour of particular instructions, and their encodings to achieve such. I am not in the mood to hunt for such legends, however.

Another thing: what does nasm -v show for you? I'm aware that more recent NASM releases should assemble from "add eax, 1" a 16-bit code sequence similar to or matching 66 83 C0 01, unless you explicitly disable this optimisation.
C. Masloch

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Is This a Problem with NASM? Seems to be.
« Reply #3 on: September 04, 2012, 07:07:07 AM »
Yeah, that was a little abrupt. Sorry. I'm still in a bad mood from losing the "long explanation".

Just for fun...
Quote
  Enter an 80x86 instruction mnemonic to convert: add eax,1
  ml.exe says "add eax,1" translates to " 83 C0 01 "
  nasm.exe says "add eax,1" translates to " 66 05 01 00 00 00 "
  fasm.exe says "add eax,1" translates to " 66 83 C0 01 "
Try "add eax, 257" (bigger than a byte). Now, Nasm and Fasm will still be generating the "wrong" code for 32-bit CPU mode. The problem is that they've been "misinformed". Tell 'em you want "bits 32", and you'll get the code you want. Curiously, all three encodings ARE correct... just not for the CPU mode you wanted.

As CM noted, Nasm won't produce that encoding (without working at it) from recent versions (correct, but longer than it needs to be - try "add eax, byte 1" for old versions). Get the latest here:
http://www.nasm.us/pub/nasm/releasebuilds/2.10.04/
No sense discussing potential "issues" in long gone by versions!

Best,
Frank