Por pura casualidad, mientras le echaba un vistazo al Lazy Assembler (LZASM), un ensamblador para DOS y Windows compatible con el modo ideal de Turbo Assembler (TASM), casi me caigo de culo al ver la cantidad de instrucciones que soportan los procesadores actuales.
A pesar de que no toco ensamblador en serio desde hace años, creo que sabría utilizar de memoria, al menos el 80% de las instrucciones 8088/8086, y digamos un 60% de las del 386. Para las arquitecturas más nuevas, digamos que las instrucciones añadidas me suenan, pero poco más.
En x87 nunca fui un experto, por lo que para hacer algo basado en un 8087, sin duda necesitaría al menos documentación de referencia.
Reconozco que programar hoy en día en assembler para aprovechar lo que da de si un microprocesador de última hornada, tiene mérito. Hablamos de usar MMX, SSE, y 3DNow!, en sus versiones más avanzadas. No me extraña que un compilador decente sea capaz de generar un código mejor que el que escribiríamos la mayoría de nosotros.
La simple enumeración de todas las instrucciones disponibles, agota…
Juego de instrucciones de propósito general en el 386:
aaa, aad, aam, aas, adc, add, and, arpl, bound, bsf, bsr, bt, btc, btr, bts, call, cbw, cdq, clc, cld, cli, clts, cmc, cmp, cmps, cmpsb, cmpsd, cmpsw, cwd, cwde, daa, das, dec, div, enter, enterd, enterw, hlt, idiv, imul, in, inc, ins, insb, insd, insw, int, into, iret, iretd, iretw, ja, jae, jb, jbe, jc, jcxz, je, jecxz, jg, jge, jl, jle, jmp, jna, jnae, jnb, jnbe, jnc, jne, jng, jnge, jnl, jnle, jno, jnp, jns, jnz, jo, jp, jpe, jpo, js, jz, lahf, lar, lds, lea, leave, leaved, leavew, les, lfs, lgdt, lgs, lidt, lldt, lmsw, lock, lods, lodsb, lodsd, lodsw, loop, loopd, loopde, loopdne, loopdnz, loopdz, loope, looped, loopew, loopne, loopned, loopnew, loopnz, loopnzd, loopnzw, loopw, loopwe, loopwne, loopwnz, loopwz, loopz, loopzd, loopzw, lsl, lss, ltr, mov, movs, movsb, movsd, movsw, movsx, movzx, mul, neg, nop, not, or, out, outs, outsb, outsd, outsw, pop, popa, popad, popaw, popf, popfd, popfw, push, pusha, pushad, pushaw, pushd, pushf, pushfd, pushfw, pushw, rcl, rcr, rep, repe, repne, repnz, repz, ret, retf, retn, rol, ror, sahf, sal, sar, sbb, scas, scasb, scasd, scasw, segcs, segds, seges, segfs, seggs, segss, seta, setae, setalc, setb, setbe, setc, sete, setg, setge, setl, setle, setna, setnae, setnb, setnbe, setnc, setne, setng, setnge, setnl, setnle, setno, setnp, setns, setnz, seto, setp, setpe, setpo, sets, setz, sgdt, shl, shld, shr, shrd, sidt, sldt, smsw, stc, std, sti, stos, stosb, stosd, stosw, str, sub, test, verr, verw, wait, xchg, xlat, xlatb, xor.
Extensión al juego de instrucciones de propósito general en el 486:
bswap, cmpxchg, invd, invlpg, smi, wbinvd, xadd.
Extensión al juego de instrucciones de propósito general en el 586:
cmpxchg8b, cpuid, rdmsr, rdtsc, wrmsr.
Extensión al juego de instrucciones de propósito general en el 686:
cmova, cmovae, cmovb, cmovbe, cmovc, cmove, cmovg, cmovge, cmovl, cmovle, cmovna, cmovnae, cmovnb, cmovnbe, cmovnc, cmovne, cmovng, cmovnge, cmovnl, cmovnle, cmovno, cmovnp, cmovns, cmovnz, cmovo, cmovp, cmovpe, cmovpo, cmovs, cmovz, rdpmc, rsm, syscall, sysenter, sysexit, sysret, ud, ud2.
Juego de instrucciones matemático en el 387:
esc, f2xm1, fabs, fadd, faddp, fbld, fbstp, fchs, fclex, fcom, fcomp, fcompp, fcos, fdecstp, fdisi, fdiv, fdivp, fdivr, fdivrp, feni, ffree, ffreep, fiadd, ficom, ficomp, fidiv, fidivr, fild, fimul, fincstp, finit, fist, fistp, fisub, fisubr, fld, fld1, fldcw, fldenv, fldenvd, fldenvw, fldl2e, fldl2t, fldlg2, fldln2, fldpi, fldz, fmul, fmulp, fnclex, fndisi, fneni, fninit, fnldenv, fnop, fnrstor, fnsave, fnsaved, fnsavew, fnstcw, fnstenv, fnstenvd, fnstenvw, fnstsw, fpatan, fprem, fprem1, fptan, frndint, frstor, frstord, frstorw, fsave, fsaved, fsavew, fscale, fsetpm, fsin, fsincos, fsqrt, fst, fstcw, fstenv, fstenvd, fstenvw, fstp, fstsw, fsub, fsubp, fsubr, fsubrp, ftst, fucom, fucomp, fucompp, fwait, fxam, fxch, fxtract, fyl2x, fyl2xp1.
Extensión al juego de instrucciones matemático en el 686:
fcmovb, fcmovbe, fcmove, fcmovnb, fcmovnbe, fcmovne, fcmovnu, fcmovu, fcomi, fcomip, fucomi, fucomip.
Juego de instrucciones MMX:
emms, movd, movq, packssdw, packsswb, packuswb, paddb, paddd, paddsb, paddsw, paddusb, paddusw, paddw, pand, pandn, pcmpeqb, pcmpeqd, pcmpeqw, pcmpgtb, pcmpgtd, pcmpgtw, pmaddwd, pmulhw, pmullw, por, pslld, psllq, psllw, psrad, psraw, psrld, psrlq, psrlw, psubb, psubd, psubsb, psubsw, psubusb, psubusw, psubw, punpckhbw, punpckhdq, punpckhwd, punpcklbw, punpckldq, punpcklwd, pxor.
Juego de instrucciones SSE:
maskmovq, movntq, pavgb, pavgw, pextrw, pinsrw, pmaxsw, pmaxub, pminsw, pminub, pmovmskb, pmulhuw, prefetchnta, prefetcht0, prefetcht1, prefetcht2, psadbw, pshufw, sfence.
Juego de instrucciones SSE2:
addpd, addsd, andnpd, andpd, clflush, cmpeqpd, cmpeqsd, cmplepd, cmplesd, cmpltpd, cmpltsd, cmpneqpd, cmpneqsd, cmpnlepd, cmpnlesd, cmpnltpd, cmpnltsd, cmpordpd, cmpordsd, cmppd, cmpsd, cmpuordpd, cmpuordsd, comisd, cvtdq2pd, cvtdq2ps, cvtpd2dq, cvtpd2pi, cvtpd2ps, cvtpi2pd, cvtps2dq, cvtps2pd, cvtsd2si, cvtsd2ss, cvtsi2sd, cvtss2sd, cvttpd2dq, cvttpd2pi, cvttps2dq, cvttsd2si, divpd, divsd, lfence, maskmovdqu, maxpd, maxsd, mfence, minpd, minsd, movapd, movd, movdq2q, movdqa, movdqu, movhpd, movlpd, movmskpd, movntdq, movnti, movntpd, movq, movq2dq, movsd, movupd, mulpd, mulsd, orpd, packssdw, packsswb, packuswb, paddb, paddd, paddq, paddsb, paddsw, paddusb, paddusw, paddw, pand, pandn, pause, pavgb, pavgw, pcmpeqb, pcmpeqd, pcmpeqw, pcmpgtb, pcmpgtd, pcmpgtw, pextrw, pinsrw, pmaddwd, pmaxsw, pmaxub, pminsw, pminub, pmovmskb, pmulhw, pmulhuw, pmullw, pmuludq, por, psadbw, pshufd, pshufhw, pshuflw, pslld, pslldq, psllq, psllw, psrad, psraw, psrld, psrldq, psrlq, psrlw, psubb, psubd, psubq, psubsb, psubsw, psubusb, psubusw, psubw, punpckhbw, punpckhdq, punpckhqdq, punpckhwd, punpcklbw, punpckldq, punpcklqdq, punpcklwd, pxor, shufpd, sqrtpd, sqrtsd, subpd, subsd, ucomisd, unpckhpd, unpcklpd, xorpd.
Juego de instrucciones SSE3:
addsubpd, addsubps, fisttp, haddpd, haddps, hsubpd, hsubps, lddqu, monitor, movddup, movshdup, movsldup, mwait.
Juego de instrucciones SSE4:
pabsb, pabsd, pabsw, palignr, phaddd, phaddsw, phaddw, phsubd, phsubsw, phsubw, pmaddubsw, pmulhrsw, pshufb, psignb, psignd, psignw.
Juego de instrucciones 3DNow!:
femms, pavgusb, pf2id, pfacc, pfadd, pfcmpeq, pfcmpge, pfcmpgt, pfmax, pfmin, pfmul, pfrcp, pfrcpit1, pfrcpit2, pfrsqit1, pfrsqrt, pfsub, pfsubr, pi2fd, pmulhrw, prefetch, prefetchw.
Juego de instrucciones 3DNow Extended:
pf2iw, pfnacc, pfpnacc, pi2fw, pswapd.
3DNow! Professional:
addps, addss, andnps, andps, cmpeqps, cmpeqss, cmpleps, cmpless, cmpltps, cmpltss, cmpneqps, cmpneqss, cmpnleps, cmpnless, cmpnltps, cmpnltss, cmpordps, cmpordss, cmpps, cmpss, cmpuordps, cmpuordss, comiss, cvtpi2ps, cvtps2pi, cvtsi2ss, cvtss2si, cvttps2pi, cvttss2si, divps, divss, fxrstor, fxsave, ldmxcsr, maxps, maxss, minps, minss, movaps, movhlps, movhps, movlhps, movlps, movmskps, movntps, movss, movups, mulps, mulss, orps, rcpps, rcpss, rsqrtps, rsqrtss, shufps, sqrtps, sqrtss, stmxcsr, subps, subss, ucomiss, unpckhps, unpcklps, xorps.
Puff O_O, la verdad es que no sabía que hubieran crecido tanto los juegos de instrucciones en ensamblador… Vaya, la verdad es que sí, no dudo de que cualquier compilador lo traducirá mejor que yo.
Y quizás lo más curioso de todo es que siendo un juego de instrucciones cisc, desde el Pentium en adelante internamente son procesadores de arquitectura risc…. contradictorio, pero real como la vida misma. Y eso que ahora ya son temas de los que no se habla, pero en su época…. ¡¡ que peleas !!
Black Hole, es paradójico pensar que un compilador de C decente puede hacerlo mejor que un humano, ¿verdad?
Polimalo, por suerte yo era de los que al discutir, defendía una arquitectura mixta CISC-RISC. En el fondo es lógico pensar que lo necesario son instrucciones muy sencillas que se ejecutan muy rapidamente y son muy paralelizables, complementado con instrucciones muy específicas.