Inline Assembler Problems_(re)

Mon, 9 Jun 1997 20:05:25 +0200 (MET DST)


According to Bernhard Tschirren:
> 
> I've hit a little snag - I cant convert one type of Intel instruction to the
> AT&T format. Take a look at the example below:
> [...]
> I couldnt figure out how to code the memory reference!

A description of GPC's inline assembler was recently posted to this list
by somebody who calls himself "Predator Zeta".  (The subject was "StOp
GrInNiNg AnD dRoP yOuR lInNeN...", so maybe you did not identify it as
something about assembler. ;-)  In case you have lost that mail, you can
retrieve it in the GPC Mailing list archive at

    ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/misc/gpc-list.1997.gz

but you can also directly download the information from

    ftp://agnes.dida.physik.uni-essen.de/gnu-pascal/contrib/gpcasm.zip

Your problem is discussed in chapter 3 (snippet below).

Hope this helps,

    Peter

 Dipl.-Phys. Peter Gerwinski, Essen, Germany, free physicist and programmer
peter.gerwinski@uni-essen.de - http://home.pages.de/~peter.gerwinski/ [970201]
 maintainer GNU Pascal [970510] - http://home.pages.de/~gnu-pascal/ [970125]

8< ---------------------------------------------------------------------------

 - 3. Memory addressing -

Intel: SELECTOR : [BASE + INDEX*SCALE + DISPLACEMENT]

AT&T:  SELECTOR : DISPLACEMENT (BASE, INDEX, SCALE)

   If you are able to decypher the scheme above, you are perfectly able to
master memory addressing. If you couldn't grasp the meaning, go on reading
this short explanation:

-The SELECTOR, for both formats, must be in the first position. The SELECTOR
 is expressed by means of a segment register(CS,DS,ES,SS,GS or FS) and
 CANNOT be an immediate value. If the selector used by the instruction is
 the default one(ES for StoS, SS for stack opcodes, DS/ES for MovS and DS
 for all the other one), you must omit both the register AND the colon.

-The BASE value is, for example, the address of the first element of an
 array. In the Intel format it is placed as the first element into the
 square braces. Can be any one of the general purpose registers.
 -The INDEX value represents, to continue the previous example, the index
 of an array. BASE + INDEX gives the address in memory of the INDEXth
 element of the array starting at BASE. INDEX should also be any one of
 the general purpose registers and can be modified by a scaling factor...

-The SCALE is an immediate value, choosen from 2, 4 or 8. When computing the
 address, INDEX is multiplied by SCALE, so that if our beloved array has
 elements made up of 2, 4 or 8 bytes, we can address them directly.

-The DISPLACEMENT, at last, is a costant immediate value to be added to the
 final address. Usually, the most common addressing schemes involve
 BASE & DISPLACEMENT or BASE & INDEX: it's very unlikely to find all of them
 in one opcode.

Mov EAX, DWord PTR FS:[EBX]     <===>   MovL %FS:(%EBX),    %EAX
Mov EDI, DWord PTR [ECX+EBX*2]  <===>   MovL (%ECX,%EBX,2), %EDI
Mov EAX, DWord PTR [12345678h]  <===>   MovL 0x12345678,    %EAX
Mov EBX, DWord PTR GS:[EDX*2]   <===>   MovL %GS:(,%EDX,2), %EBX
Mov EAX, DWord PTR [ECX+12345h] <===>   MovL 0x12345(%ECX), %EAX
Mov EDI, DWord PTR ES:[12345h]  <===>   MovL %ES:0x12345,   %EDI
Mov BX,  Word PTR [_MyVar]      <===>   MovW (_MyVar),      %BX

Now for some highlights:

Have a look at the third example: did you notice that in the AT&T syntax
there is no dollar sign("$") preceding the value 0x12435678? That's perfectly
right... if you look at the Intel syntax, you'll notice that it is a memory
reference, not an immediate value:

_In AT&T syntax, __EVERY__ immediate value WITHOUT a dollar sign preceding it
 is considered a memory reference_

Now, what about the forth example? Is that comma in the right place?
The answer is YES, and it is very important to understand why. In this opcode
the BASE is null. If we omitted the comma, the assembler would have guessed
wrong and would have produced this:

Mov EBX, DWord PTR GS:[EDX]   <===>   MovL %GS:(%EDX,2), %EBX

The "2", mistaken for a scale, would have been discarded and EDX would have
been the only register to be considered... a BAD error indeed!
__ALWAYS__ put 3 commas between the braces, whatever you want to do!



Peter Gerwinski (peter@agnes.dida.physik.uni-essen.de)

HTML conversion by Lluís de Yzaguirre i Maura
Institut de Lingüística Aplicada - Universitat "Pompeu Fabra"
e-mail: de_yza@upf.es