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!