Combuster wrote:what I miss is that GAS uses different opcodes than what the intel manuals state, even beyond the suffixed b/w/l
Most of these differences came from history. And many of them are irrelevant to almost anybody, like clr, or smov/ssca/scmp etc.
Beyond the suffix (which came in also in Intel syntax for MMX and SSE, by the way) and what is covered below, what really matters are the two-suffixes operations, the equivalent of CBW and friends, where you have to learn that it reads c+
srcSuffix+t+
dstSuffix; and MOVSX/MOVZX where GAS drops the X (don't know why, makes it shorter?) and adds the two suffixes: quite frankly, it does not appear that complex to me, at least much more easy than the reversal of the operands or the % prefix.
Intel syntax also has some strange aliases, like XLAT/XLATB (not every assemblers have both); IRET meaning the same, or
not, as IRETD (in 32-bit code); the type of the BOUND operand; or the stack operations for the 87 (FADD without operands, meaning FADDP st(1), st)
like far jumps use the ljmp opcode, which means that in some os-related cases you'll have to figure out what the corresponding opcode is in GAS while in nasm you can simply copy the name from the intel manuals.
Well, the
far operations is where there are the largest divergences in
any x86 assemblers, and this began with the early ones: Intel used JMP/CALL/RET with special types (including procedures), but DRI and many "tools" assemblers like
DEBUG used JMPF/CALLF/RETF (+RETN), early Unix assemblers chose jmpi/calli/reti (i for intersegment, but it could be read intrasegment as well...), until ISC chose yet another one for the 80286 System V as, that is ljmp/lcall/lret (I do not know why).
All of this was
before the mess created by the 80386 16/32 mixup,
SMALL/LARGE or
WORD/DWORD or
DWORD/PWORD etc.
However, the main problem I have with these instructions is much more related to the difficulty to know the syntax, particularly whether the segment should come first or second, or whether the "clever" assembler will "simplify" my far call into a push+near_call
. I believe I am not alone, since I often encounter code where the JMPF to 32-bit mode is coded as
Code: Select all
.byte 0xEA ; .word 1f, THISSEG; 1:
and then there's the fact that GAS is crippled when it comes to writing [ 16 ]-bit programs
In this area, GAS made real progresses in the last years. What was really a mess 10 years ago is now almost doable.
Yes there are probably bugs remaining, but as in every GNU tool, there are (small) bugs because nobody use that code, and nobody use that code because there were (big) bugs.