From 4836e3374e813e6719a8da764bcb20701e4931a0 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Tue, 30 Apr 2002 20:56:43 +0000 Subject: [PATCH] NASM 0.98p3.5 --- MODIFIED | 24 ++++ Readme | 183 ++++++++------------------ assemble.c | 33 ++--- c16.mac | 123 +++++++++++------ c32.mac | 78 +++++++---- changes.asm | 24 ++++ disasm.c | 93 +++++++------ disasm.h | 2 +- exebin.mac | 171 ++++++++++++++++-------- insns.dat | 385 +++++++++++++++++++++++++++++++++++++++++------------- insns.h | 45 ++++--- names.c | 3 +- nasm.h | 6 +- ndisasm.c | 27 +++- parser.c | 3 +- preproc.c | 38 ++++-- rdoff/Makefile.sc | 58 ++++++++ 17 files changed, 860 insertions(+), 436 deletions(-) rewrite Readme (99%) diff --git a/MODIFIED b/MODIFIED index 60a49e0c..4e0ddb15 100644 --- a/MODIFIED +++ b/MODIFIED @@ -2,6 +2,30 @@ This is a modified version of NASM, modified and released by H. Peter Anvin ; it is not the original form released by the NASM authors. +For release 0.98p3.5: + +* Merged in changes from John S. Fine's 0.98-J5 release. John's based + 0.98-J5 on my 0.98p3.3 release; this merges the changes. +* Expanded the instructions flag field to a long so we can fit more + flags; mark SSE (KNI) and AMD or Katmai-specific instructions as + such. +* Fix the "PRIV" flag on a bunch of instructions, and create new + "PROT" flag for protected-mode-only instructions (orthogonal to if + the instruction is privileged!) and new "SMM" flag for SMM-only + instructions. +* Added AMD-only SYSCALL and SYSRET instructions. +* Make SSE actually work, and add new Katmai MMX instructions. +* Added a -p (preferred vendor) option to ndisasm so that it can + distinguish e.g. Cyrix opcodes also used in SSE. For example: + + ndisasm -p cyrix aliased.bin + 00000000 670F514310 paddsiw mm0,[ebx+0x10] + 00000005 670F514320 paddsiw mm0,[ebx+0x20] + ndisasm -p intel aliased.bin + 00000000 670F514310 sqrtps xmm0,[ebx+0x10] + 00000005 670F514320 sqrtps xmm0,[ebx+0x20] +* Added a bunch of Cyrix-specific instructions. + For release 0.98p3.4: * Made at least an attempt to modify all the additional Makefiles (in diff --git a/Readme b/Readme dissimilarity index 99% index 11fb184e..6e7c56c7 100644 --- a/Readme +++ b/Readme @@ -1,130 +1,53 @@ -This is a distribution of NASM, the Netwide Assembler. NASM is a -prototype general-purpose x86 assembler. It will currently output -flat-form binary files, a.out, COFF and ELF Unix object files, -Microsoft Win32 and 16-bit DOS object files, OS/2 object files, the -as86 object format, and a home-grown format called RDF. - -Also included is NDISASM, a prototype x86 binary-file disassembler -which uses the same instruction table as NASM. - -To install NASM on Linux, type `make', and then when it has finished -copy the file `nasm' (and maybe `ndisasm') to a directory on your -search path (maybe /usr/local/bin, or ~/bin if you don't have root -access). You may also want to copy the man page `nasm.1' (and maybe -`ndisasm.1') to somewhere sensible. - -To install under DOS, if you don't need to rebuild from the sources, -you can just copy nasm.exe and ndisasm.exe (16-bit DOS executables), -or nasmw.exe and ndisasmw.exe (Win32 console applications - less -likely to run out of memory), to somewhere on your PATH. - -To rebuild the DOS sources, various makefiles are provided: - -- Makefile.dos, the one I build the standard 16-bit releases from, - designed for a hybrid system using Microsoft C and Borland Make - (don't ask why :-) -- Makefile.vc, for Microsoft Visual C++ compiling to a Win32 - command-line application. This is the one I build the standard - Win32 release binaries from. - -- Makefile.bor, for Borland C. -- Makefile.bc2, also for Borland C, contributed by Fox Cutter. - Reported to work better than Makefile.bor on some systems. - -- Makefile.sc, for Symantec C++, compiling to a 32-bit extended DOS - executable.. Contributed by Mark Junker. -- Makefile.scw, also for Symantec C++, compiling to a Win32 command- - line application. Also contributed by Mark Junker. - -- Makefile.wc, for Watcom C, compiling to a 32-bit extended DOS - executable. Contributed by Dominik Behr. -- Makefile.wcw, also for Watcom C, compiling to a Win32 command- - line application. Also contributed by Dominik Behr. - -- Makefile.dj, for DJGPP, compiling to a 32-bit extended DOS - executable. Contributed by Dominik Behr. - -- Makefile.lcc, for lcc-win32, compiling to a Win32 command line - application. (The lcc-win32 compiler and tools are available from - http://www.remcomp.com/lcc-win32/) - -I can't guarantee that all of those makefiles work, because I don't -have all of those compilers. However, Makefile.dos and Makefile.vc -work on my system, and so do Makefile.bor and Makefile.bc2. - -Be careful with Borland C: there have been various conflicting -reports about how reliable the Huge memory model is. If you try to -compile NASM in Large model, you may get DGROUP overflows due to the -vast quantity of data in the instruction tables. I've had reports -from some people that Huge model doesn't work at all (and also -reports from others that it works fine), so if you don't want to try -moving to Huge, you could try adding the option `-dc' to the -compiler command line instead, which causes string literals to be -moved from DGROUP to the code segments and might make Large model -start working. (Either solution works for me.) - -Dominik Behr has also contributed the file misc/pmw.bat, which is a -batch file to turn the output from Makefile.wc (NASM.EXE and -NDISASM.EXE) into standalone executables incorporating Tran's -PMODE/W DOS extender, rather than depending on an external extender -program. - -Some of the Windows makefiles produce executables called nasmw.exe -and ndisasmw.exe, and some don't. Be prepared for either... - -If you're trying to unpack the DOS (.ZIP format) archive under Unix -instead of using the .tar.gz version, you can save some time by -doing `unzip -aL', which will convert the DOS-format text files to -Unix and also convert all names to lower case. - -If you want to build a restricted version of NASM containing only -some of the object file formats, you can achieve this by adding -#defines to `outform.h' (see the file itself for documentation), or -equivalently by adding compiler command line options in the -Makefile. - -There is a machine description file for the `LCC' retargetable C -compiler (version 3.6), in the directory `lcc', along with -instructions for its use. This means that NASM can now be used as -the code-generator back end for a useful C compiler. - -Michael `Wuschel' Tippach has ported his DOS extender `WDOSX' to -enable it to work with the 32-bit binary files NASM can output: the -original extender and his port `WDOSX/N' are available from his web -page, http://www.geocities.com/SiliconValley/Park/4493. - -Matt Mastracci has written a document explaining how to write -assembly language modules in DJGPP programs using NASM: it's on his -web site at http://www.ucalgary.ca/~mmastrac/djgppasm.doc. - -The `misc' directory contains `nasm.sl', a NASM editing mode for the -JED programmers' editor (see http://space.mit.edu/~davis/jed.html -for details about JED). The comment at the start of the file gives -instructions on how to install the mode. This directory also -contains a file (`magic') containing lines to add to /etc/magic on -Unix systems to allow the `file' command to recognise RDF files, and -a zip file (`exasm.zip') containing the necessary files for syntax -highlighting in the Aurora DOS editor. (The Aurora files were -contributed by ; I haven't tested them as I -don't have Aurora.) - -The `rdoff' directory contains sources for a linker and loader for -the RDF object file format, to run under Linux, and also -documentation on the internal structure of RDF files. - -For information about how you can distribute and use NASM, see the -file Licence. We were tempted to put NASM under the GPL, but decided -that in many ways it was too restrictive for developers. - -For information about how to use NASM, see the various forms of -documentation in the `doc' directory: documentation is provided in -HTML, PostScript, plain text, Texinfo, and Windows Help formats. For -information about how to use NDISASM, see `ndisasm.doc'. For -information about the internal structure of NASM, see -`internal.doc'. (In particular, _please_ read `internal.doc' before -writing any code for us...) - -The NASM web page is at http://www.cryogen.com/Nasm/ - -Bug reports (and patches if you can) should be sent to - or . +This directory contains the necessary files to port the C compiler +``LCC'' (available by FTP from sunsite.doc.ic.ac.uk in the directory +/computing/programming/languages/c/lcc) to compile for Linux (a.out or +ELF) or other supported operating systems by using NASM as a back-end +code generator. + +This patch has been tested on lcc version 4.0. + +To install: + +- Copy `x86nasm.md' into the `src' directory of the lcc tree. + +- Copy either `lin-elf.c' or `lin-aout.c' into the `etc' directory. + +- With previous versions, you had to modify x86-nasm.md if you weren't + using ELF. There is now inbuilt support within NASM in the shape + of the __CDECL__ macro, so this modification is no longer necessary. + +- Make the following changes to `bind.c' in the `src' directory: + + - Near the top of the file, add a line that reads + extern Interface x86nasmIR; + + - In the `bindings' array, add the lines + "x86-nasm", &x86nasmIR, + "x86/nasm", &x86nasmIR, + (in sensible looking places...) + + A sample `bind.c' has been provided to show what the result of + this might look like. You might be able to get away with using it + directly... + +- Modify the lcc makefile to include rules for x86nasm.o: this will + have to be done in about three places. Just copy any line with + `x86' on it and modify it to read `x86nasm' everywhere. (Except + that in the list of object files that rcc is made up from, do + remember to ensure that every line but the last has a trailing + backslash...) + +- You may have to modify the contents of `lin-elf.c' or `lin-aout.c' + to reflect the true locations of files such as crt0.o, crt1.o, + ld-linux.so and so forth. If you don't know where to find these, + compile a short C program with `gcc -v' and see what command line + gcc feeds to `ld'. + +- You should now be able to build lcc, using `lin-elf.c' or + `lin-aout.c' as the system-dependent part of the `lcc' wrapper + program. + +- Symlink x86nasm.c into the `src' directory before attempting the + triple test, or the compile will fail. + +- Now it should pass the triple test, on either ELF or a.out. Voila! diff --git a/assemble.c b/assemble.c index 65bcea39..ae1de206 100644 --- a/assemble.c +++ b/assemble.c @@ -611,7 +611,7 @@ static void gencode (long segment, long offset, int bits, case R_SS: bytes[0] = 0x16 + (c == 0x04 ? 1 : 0); break; default: - errfunc (ERR_PANIC, "bizarre 8086 segment register received"); + errfunc (ERR_PANIC, "bizarre 8086 segment register received"); } out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG); offset++; @@ -622,7 +622,7 @@ static void gencode (long segment, long offset, int bits, case R_FS: bytes[0] = 0xA0 + (c == 0x05 ? 1 : 0); break; case R_GS: bytes[0] = 0xA8 + (c == 0x05 ? 1 : 0); break; default: - errfunc (ERR_PANIC, "bizarre 386 segment register received"); + errfunc (ERR_PANIC, "bizarre 386 segment register received"); } out (offset, segment, bytes, OUT_RAWDATA+1, NO_SEG, NO_SEG); offset++; @@ -928,31 +928,31 @@ static int regval (operand *o) { switch (o->basereg) { case R_EAX: case R_AX: case R_AL: case R_ES: case R_CR0: case R_DR0: - case R_ST0: case R_MM0: + case R_ST0: case R_MM0: case R_XMM0: return 0; case R_ECX: case R_CX: case R_CL: case R_CS: case R_DR1: case R_ST1: - case R_MM1: + case R_MM1: case R_XMM1: return 1; case R_EDX: case R_DX: case R_DL: case R_SS: case R_CR2: case R_DR2: - case R_ST2: case R_MM2: + case R_ST2: case R_MM2: case R_XMM2: return 2; case R_EBX: case R_BX: case R_BL: case R_DS: case R_CR3: case R_DR3: - case R_TR3: case R_ST3: case R_MM3: + case R_TR3: case R_ST3: case R_MM3: case R_XMM3: return 3; case R_ESP: case R_SP: case R_AH: case R_FS: case R_CR4: case R_TR4: - case R_ST4: case R_MM4: + case R_ST4: case R_MM4: case R_XMM4: return 4; case R_EBP: case R_BP: case R_CH: case R_GS: case R_TR5: case R_ST5: - case R_MM5: + case R_MM5: case R_XMM5: return 5; case R_ESI: case R_SI: case R_DH: case R_DR6: case R_TR6: case R_ST6: - case R_MM6: + case R_MM6: case R_XMM6: return 6; case R_EDI: case R_DI: case R_BH: case R_DR7: case R_TR7: case R_ST7: - case R_MM7: + case R_MM7: case R_XMM7: return 7; default: /* panic */ - errfunc (ERR_PANIC, "invalid register operand given to regval()"); + errfunc (ERR_PANIC, "invalid register operand given to regval()"); return 0; } } @@ -1031,10 +1031,11 @@ static ea *process_ea (operand *input, ea *output, int addrbits, int rfield, { if (!(REGISTER & ~input->type)) { /* it's a single register */ static int regs[] = { - R_MM0, R_EAX, R_AX, R_AL, R_MM1, R_ECX, R_CX, R_CL, - R_MM2, R_EDX, R_DX, R_DL, R_MM3, R_EBX, R_BX, R_BL, - R_MM4, R_ESP, R_SP, R_AH, R_MM5, R_EBP, R_BP, R_CH, - R_MM6, R_ESI, R_SI, R_DH, R_MM7, R_EDI, R_DI, R_BH + R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH, + R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI, + R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI, + R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7, + R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7 }; int i; @@ -1043,7 +1044,7 @@ static ea *process_ea (operand *input, ea *output, int addrbits, int rfield, if (isib_present = FALSE;/* no SIB necessary */ output->bytes = 0; /* no offset necessary either */ - output->modrm = 0xC0 | (rfield << 3) | (i/4); + output->modrm = 0xC0 | (rfield << 3) | (i & 7); } else return NULL; diff --git a/c16.mac b/c16.mac index 2853db51..50b5d5ee 100644 --- a/c16.mac +++ b/c16.mac @@ -1,41 +1,82 @@ -; NASM macro set to make interfacing to 16-bit programs easier -*- nasm -*- - -%imacro proc 1 ; begin a procedure definition -%push proc - global %1 -%1: push bp - mov bp,sp -%ifdef FARCODE PASCAL ; arguments may start at bp+4 or bp+6 -%assign %$arg 6 -%define %$firstarg 6 -%else -%assign %$arg 4 -%define %$firstarg 4 -%endif -%define %$procname %1 -%endmacro - -%imacro arg 0-1 2 ; used with the argument name as a label -%00 equ %$arg - ; we could possibly be adding some - ; debug information at this point...? -%assign %$arg %1+%$arg -%endmacro - -%imacro endproc 0 -%ifnctx proc -%error Mismatched `endproc'/`proc' -%else - mov sp,bp - pop bp -%ifdef PASCAL - retf %$arg - %$firstarg -%elifdef FARCODE - retf -%else - retn -%endif -__end_%$procname: ; useful for calculating function size -%pop -%endif -%endmacro +; NASM macro set to make interfacing to 16-bit programs easier -*- nasm -*- + + + +%imacro proc 1 ; begin a procedure definition + +%push proc + + global %1 + +%1: push bp + + mov bp,sp + +%ifdef FARCODE PASCAL ; arguments may start at bp+4 or bp+6 + +%assign %$arg 6 + +%define %$firstarg 6 + +%else + +%assign %$arg 4 + +%define %$firstarg 4 + +%endif + +%define %$procname %1 + +%endmacro + + + +%imacro arg 0-1 2 ; used with the argument name as a label + +%00 equ %$arg + + ; we could possibly be adding some + + ; debug information at this point...? + +%assign %$arg %1+%$arg + +%endmacro + + + +%imacro endproc 0 + +%ifnctx proc + +%error Mismatched `endproc'/`proc' + +%else + + mov sp,bp + + pop bp + +%ifdef PASCAL + + retf %$arg - %$firstarg + +%elifdef FARCODE + + retf + +%else + + retn + +%endif + +__end_%$procname: ; useful for calculating function size + +%pop + +%endif + +%endmacro + diff --git a/c32.mac b/c32.mac index 6abad995..f0c116ba 100644 --- a/c32.mac +++ b/c32.mac @@ -1,26 +1,52 @@ -; NASM macro set to make interfacing to 32-bit programs easier -*- nasm -*- - -%imacro proc 1 ; begin a procedure definition -%push proc - global %1 -%1: push ebp - mov ebp,esp -%assign %$arg 8 -%define %$procname %1 -%endmacro - -%imacro arg 0-1 4 ; used with the argument name as a label -%00 equ %$arg -%assign %$arg %1+%$arg -%endmacro - -%imacro endproc 0 -%ifnctx proc -%error Mismatched `endproc'/`proc' -%else - leave - ret -__end_%$procname: ; useful for calculating function size -%pop -%endif -%endmacro +; NASM macro set to make interfacing to 32-bit programs easier -*- nasm -*- + + + +%imacro proc 1 ; begin a procedure definition + +%push proc + + global %1 + +%1: push ebp + + mov ebp,esp + +%assign %$arg 8 + +%define %$procname %1 + +%endmacro + + + +%imacro arg 0-1 4 ; used with the argument name as a label + +%00 equ %$arg + +%assign %$arg %1+%$arg + +%endmacro + + + +%imacro endproc 0 + +%ifnctx proc + +%error Mismatched `endproc'/`proc' + +%else + + leave + + ret + +__end_%$procname: ; useful for calculating function size + +%pop + +%endif + +%endmacro + diff --git a/changes.asm b/changes.asm index 05b6788e..2601a01c 100644 --- a/changes.asm +++ b/changes.asm @@ -98,6 +98,19 @@ forwardref: %endmacro xxx yyy +;----------------------------------------------------------------------------- +; Bug added by John in preproc.c 0.98-J4, removed by John in 0.98-J5 +; +; Tested here to make sure it stays removed +; +%macro TestElse 1 +%if %1=0 +%elif %1=1 +nop +%endif +%endmacro +TestElse 1 + %ifdef oldmsg ;*************************************************************** ; @@ -280,9 +293,20 @@ arg_example2 arg2 ud2 sysenter sysexit + syscall + sysret fxsave [ebx] fxrstor [es:ebx+esi*4+0x3000] +;----------------------------------------------------------------------------- +; Enhancement by hpa in insns.dat et al +; +; Actually make SSE work, and use the -p option to ndisasm to select +; one of several aliased opcodes +; + sqrtps xmm0,[ebx+10] ; SSE opcode + paddsiw mm0,[ebx+10] ; Cyrix opcode with the same byte seq. + %endif %ifdef oldcrash ;************************************************************* diff --git a/disasm.c b/disasm.c index 4764bc16..ba76097b 100644 --- a/disasm.c +++ b/disasm.c @@ -53,6 +53,8 @@ static int whichreg(long regflags, int regval) R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, R_ST6, R_ST7 }; static int mmxreg[] = { R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7 }; + static int xmmreg[] = { + R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7 }; if (!(REG_AL & ~regflags)) return R_AL; @@ -96,6 +98,8 @@ static int whichreg(long regflags, int regval) return fpureg[regval]; if (!(MMXREG & ~regflags)) return mmxreg[regval]; + if (!(XMMREG & ~regflags)) + return xmmreg[regval]; return 0; } @@ -445,15 +449,16 @@ static int matches (unsigned char *r, unsigned char *data, int asize, } long disasm (unsigned char *data, char *output, int segsize, long offset, - int autosync) + int autosync, unsigned long prefer) { - struct itemplate **p; - int length = 0; + struct itemplate **p, **best_p; + int length, best_length = 0; char *segover; int rep, lock, asize, osize, i, slen, colon; unsigned char *origdata; int works; insn ins; + unsigned long goodness, best; /* * Scan for prefixes. @@ -489,45 +494,55 @@ long disasm (unsigned char *data, char *output, int segsize, long offset, ins.oprs[0].addr_size = ins.oprs[1].addr_size = ins.oprs[2].addr_size = (segsize == 16 ? 0 : SEG_32BIT); ins.condition = -1; - works = TRUE; - for (p = itable[*data]; *p; p++) - if ( (length = matches((unsigned char *)((*p)->code), data, - asize, osize, segsize, &ins)) ) - { - works = TRUE; - /* - * Final check to make sure the types of r/m match up. - */ - for (i = 0; i < (*p)->operands; i++) - if ( - - /* If it's a mem-only EA but we have a register, die. */ - ((ins.oprs[i].segment & SEG_RMREG) && - !(MEMORY & ~(*p)->opd[i])) || - - /* If it's a reg-only EA but we have a memory ref, die. */ - (!(ins.oprs[i].segment & SEG_RMREG) && - !(REGNORM & ~(*p)->opd[i]) && - !((*p)->opd[i] & REG_SMASK)) || - - /* Register type mismatch (eg FS vs REG_DESS): die. */ - ((((*p)->opd[i] & (REGISTER | FPUREG)) || - (ins.oprs[i].segment & SEG_RMREG)) && - !whichreg ((*p)->opd[i], ins.oprs[i].basereg))) - { - works = FALSE; - /* - * FIXME: can we do a break here? - */ - } - - if (works) - break; - } + best = ~0UL; /* Worst possible */ + best_p = NULL; + for (p = itable[*data]; *p; p++) { + if ( (length = matches((unsigned char *)((*p)->code), data, + asize, osize, segsize, &ins)) ) { + works = TRUE; + /* + * Final check to make sure the types of r/m match up. + */ + for (i = 0; i < (*p)->operands; i++) { + if ( + + /* If it's a mem-only EA but we have a register, die. */ + ((ins.oprs[i].segment & SEG_RMREG) && + !(MEMORY & ~(*p)->opd[i])) || + + /* If it's a reg-only EA but we have a memory ref, die. */ + (!(ins.oprs[i].segment & SEG_RMREG) && + !(REGNORM & ~(*p)->opd[i]) && + !((*p)->opd[i] & REG_SMASK)) || + + /* Register type mismatch (eg FS vs REG_DESS): die. */ + ((((*p)->opd[i] & (REGISTER | FPUREG)) || + (ins.oprs[i].segment & SEG_RMREG)) && + !whichreg ((*p)->opd[i], ins.oprs[i].basereg))) { + works = FALSE; + break; + } + } + + if (works) { + goodness = ((*p)->flags & IF_PFMASK) ^ prefer; + if ( goodness < best ) { + /* This is the best one found so far */ + best = goodness; + best_p = p; + best_length = length; + } + } + } + } - if (!length || !works) + if (!best_p ) return 0; /* no instruction was matched */ + /* Pick the best match */ + p = best_p; + length = best_length; + slen = 0; if (rep) { diff --git a/disasm.h b/disasm.h index 845fd2e4..16cdbda0 100644 --- a/disasm.h +++ b/disasm.h @@ -12,7 +12,7 @@ #define INSN_MAX 32 /* one instruction can't be longer than this */ long disasm (unsigned char *data, char *output, int segsize, long offset, - int autosync); + int autosync, unsigned long prefer); long eatbyte (unsigned char *data, char *output); #endif diff --git a/exebin.mac b/exebin.mac index 022183fa..89c68898 100644 --- a/exebin.mac +++ b/exebin.mac @@ -1,57 +1,114 @@ -; -*- nasm -*- -; NASM macro file to allow the `bin' output format to generate -; simple .EXE files by constructing the EXE header by hand. -; Adapted from a contribution by Yann Guidon - -%define EXE_stack_size EXE_realstacksize - -%macro EXE_begin 0 - ORG 0E0h - section .text - -header_start: - db 4Dh,5Ah ; EXE file signature - dw EXE_allocsize % 512 - dw (EXE_allocsize + 511) / 512 - dw 0 ; relocation information: none - dw (header_end-header_start)/16 ; header size in paragraphs - dw (EXE_absssize + EXE_realstacksize) / 16 ; min extra mem - dw (EXE_absssize + EXE_realstacksize) / 16 ; max extra mem - dw -10h ; Initial SS (before fixup) - dw EXE_endbss + EXE_realstacksize ; Initial SP (1K DPMI+1K STACK) - dw 0 ; (no) Checksum - dw 100h ; Initial IP - start just after the header - dw -10h ; Initial CS (before fixup) - dw 0 ; file offset to relocation table: none - dw 0 ; (no overlay) - align 16,db 0 -header_end: - -EXE_startcode: - section .data -EXE_startdata: - section .bss -EXE_startbss: -%endmacro - -%macro EXE_stack 1 -EXE_realstacksize equ %1 -%define EXE_stack_size EXE_bogusstacksize ; defeat EQU in EXE_end -%endmacro - -%macro EXE_end 0 - section .text -EXE_endcode: - section .data -EXE_enddata: - section .bss - alignb 4 -EXE_endbss: - -EXE_acodesize equ (EXE_endcode-EXE_startcode+3) & (~3) -EXE_datasize equ EXE_enddata-EXE_startdata -EXE_absssize equ (EXE_endbss-EXE_startbss+3) & (~3) -EXE_allocsize equ EXE_acodesize + EXE_datasize - -EXE_stack_size equ 0x800 ; default if nothing else was used -%endmacro +; -*- nasm -*- + +; NASM macro file to allow the `bin' output format to generate + +; simple .EXE files by constructing the EXE header by hand. + +; Adapted from a contribution by Yann Guidon + + + +%define EXE_stack_size EXE_realstacksize + + + +%macro EXE_begin 0 + + ORG 0E0h + + section .text + + + +header_start: + + db 4Dh,5Ah ; EXE file signature + + dw EXE_allocsize % 512 + + dw (EXE_allocsize + 511) / 512 + + dw 0 ; relocation information: none + + dw (header_end-header_start)/16 ; header size in paragraphs + + dw (EXE_absssize + EXE_realstacksize) / 16 ; min extra mem + + dw (EXE_absssize + EXE_realstacksize) / 16 ; max extra mem + + dw -10h ; Initial SS (before fixup) + + dw EXE_endbss + EXE_realstacksize ; Initial SP (1K DPMI+1K STACK) + + dw 0 ; (no) Checksum + + dw 100h ; Initial IP - start just after the header + + dw -10h ; Initial CS (before fixup) + + dw 0 ; file offset to relocation table: none + + dw 0 ; (no overlay) + + align 16,db 0 + +header_end: + + + +EXE_startcode: + + section .data + +EXE_startdata: + + section .bss + +EXE_startbss: + +%endmacro + + + +%macro EXE_stack 1 + +EXE_realstacksize equ %1 + +%define EXE_stack_size EXE_bogusstacksize ; defeat EQU in EXE_end + +%endmacro + + + +%macro EXE_end 0 + + section .text + +EXE_endcode: + + section .data + +EXE_enddata: + + section .bss + + alignb 4 + +EXE_endbss: + + + +EXE_acodesize equ (EXE_endcode-EXE_startcode+3) & (~3) + +EXE_datasize equ EXE_enddata-EXE_startdata + +EXE_absssize equ (EXE_endbss-EXE_startbss+3) & (~3) + +EXE_allocsize equ EXE_acodesize + EXE_datasize + + + +EXE_stack_size equ 0x800 ; default if nothing else was used + +%endmacro + diff --git a/insns.dat b/insns.dat index 425d0a82..deb5b118 100644 --- a/insns.dat +++ b/insns.dat @@ -85,8 +85,8 @@ AND rm32,imm \321\300\1\x81\204\41 386,SM AND mem,imm8 \300\1\x80\204\21 8086,SM AND mem,imm16 \320\300\1\x81\204\31 8086,SM AND mem,imm32 \321\300\1\x81\204\41 386,SM -ARPL mem,reg16 \300\1\x63\101 286,PRIV,SM -ARPL reg16,reg16 \300\1\x63\101 286,PRIV +ARPL mem,reg16 \300\1\x63\101 286,PROT,SM +ARPL reg16,reg16 \300\1\x63\101 286,PROT BOUND reg16,mem \320\301\1\x62\110 186 BOUND reg32,mem \321\301\1\x62\110 386 BSF reg16,mem \320\301\2\x0F\xBC\110 386,SM @@ -273,7 +273,7 @@ FDIVR fpureg \1\xD8\10\xF8 8086,FPU FDIVR fpu0,fpureg \1\xD8\11\xF8 8086,FPU FDIVRP fpureg \1\xDE\10\xF0 8086,FPU FDIVRP fpureg,fpu0 \1\xDE\10\xF0 8086,FPU -FEMMS void \2\x0F\x0E PENT,MMX,FPU +FEMMS void \2\x0F\x0E PENT,3DNOW FENI void \3\x9B\xDB\xE0 8086,FPU FFREE fpureg \1\xDD\10\xC0 8086,FPU FIADD mem32 \300\1\xDA\200 8086,FPU @@ -387,12 +387,10 @@ FXCH void \2\xD9\xC9 8086,FPU FXCH fpureg \1\xD9\10\xC8 8086,FPU FXCH fpureg,fpu0 \1\xD9\10\xC8 8086,FPU FXCH fpu0,fpureg \1\xD9\11\xC8 8086,FPU -FXRSTOR mem \300\2\x0F\xAE\202 P6,FPU -FXSAVE mem \300\2\x0F\xAE\200 P6,FPU FXTRACT void \2\xD9\xF4 8086,FPU FYL2X void \2\xD9\xF1 8086,FPU FYL2XP1 void \2\xD9\xF9 8086,FPU -HLT void \1\xF4 8086 +HLT void \1\xF4 8086,PRIV IBTS mem,reg16 \320\300\2\x0F\xA7\101 386,SW,UNDOC,ND IBTS reg16,reg16 \320\300\2\x0F\xA7\101 386,UNDOC,ND IBTS mem,reg32 \321\300\2\x0F\xA7\101 386,SD,UNDOC,ND @@ -441,8 +439,8 @@ INT1 void \1\xF1 386 INT03 void \1\xCC 8086,ND INT3 void \1\xCC 8086 INTO void \1\xCE 8086 -INVD void \2\x0F\x08 486 -INVLPG mem \300\2\x0F\x01\207 486 +INVD void \2\x0F\x08 486,PRIV +INVLPG mem \300\2\x0F\x01\207 486,PRIV IRET void \322\1\xCF 8086 IRETD void \321\1\xCF 386 IRETW void \320\1\xCF 8086 @@ -469,10 +467,10 @@ JMP mem \322\300\1\xFF\204 8086 JMP mem16 \320\300\1\xFF\204 8086 JMP mem32 \321\300\1\xFF\204 386 LAHF void \1\x9F 8086 -LAR reg16,mem \320\301\2\x0F\x02\110 286,PRIV,SM -LAR reg16,reg16 \320\301\2\x0F\x02\110 286,PRIV -LAR reg32,mem \321\301\2\x0F\x02\110 286,PRIV,SM -LAR reg32,reg32 \321\301\2\x0F\x02\110 286,PRIV +LAR reg16,mem \320\301\2\x0F\x02\110 286,PROT,SM +LAR reg16,reg16 \320\301\2\x0F\x02\110 286,PROT +LAR reg32,mem \321\301\2\x0F\x02\110 286,PROT,SM +LAR reg32,reg32 \321\301\2\x0F\x02\110 286,PROT LDS reg16,mem \320\301\1\xC5\110 8086 LDS reg32,mem \321\301\1\xC5\110 8086 LEA reg16,mem \320\301\1\x8D\110 8086 @@ -486,9 +484,9 @@ LGDT mem \300\2\x0F\x01\202 286,PRIV LGS reg16,mem \320\301\2\x0F\xB5\110 386 LGS reg32,mem \321\301\2\x0F\xB5\110 386 LIDT mem \300\2\x0F\x01\203 286,PRIV -LLDT mem \300\1\x0F\17\202 286,PRIV -LLDT mem16 \300\1\x0F\17\202 286,PRIV -LLDT reg16 \300\1\x0F\17\202 286,PRIV +LLDT mem \300\1\x0F\17\202 286,PROT,PRIV +LLDT mem16 \300\1\x0F\17\202 286,PROT,PRIV +LLDT reg16 \300\1\x0F\17\202 286,PROT,PRIV LMSW mem \300\2\x0F\x01\206 286,PRIV LMSW mem16 \300\2\x0F\x01\206 286,PRIV LMSW reg16 \300\2\x0F\x01\206 286,PRIV @@ -512,15 +510,15 @@ LOOPNZ imm,reg_ecx \311\1\xE0\50 386 LOOPZ imm \312\1\xE1\50 8086 LOOPZ imm,reg_cx \310\1\xE1\50 8086 LOOPZ imm,reg_ecx \311\1\xE1\50 386 -LSL reg16,mem \320\301\2\x0F\x03\110 286,PRIV,SM -LSL reg16,reg16 \320\301\2\x0F\x03\110 286,PRIV -LSL reg32,mem \321\301\2\x0F\x03\110 286,PRIV,SM -LSL reg32,reg32 \321\301\2\x0F\x03\110 286,PRIV +LSL reg16,mem \320\301\2\x0F\x03\110 286,PROT,SM +LSL reg16,reg16 \320\301\2\x0F\x03\110 286,PROT +LSL reg32,mem \321\301\2\x0F\x03\110 286,PROT,SM +LSL reg32,reg32 \321\301\2\x0F\x03\110 286,PROT LSS reg16,mem \320\301\2\x0F\xB2\110 386 LSS reg32,mem \321\301\2\x0F\xB2\110 386 -LTR mem \300\1\x0F\17\203 286,PRIV -LTR mem16 \300\1\x0F\17\203 286,PRIV -LTR reg16 \300\1\x0F\17\203 286,PRIV +LTR mem \300\1\x0F\17\203 286,PROT,PRIV +LTR mem16 \300\1\x0F\17\203 286,PROT,PRIV +LTR reg16 \300\1\x0F\17\203 286,PROT,PRIV MOV mem,reg_cs \320\300\1\x8C\201 8086,SM MOV mem,reg_dess \320\300\1\x8C\101 8086,SM MOV mem,reg_fsgs \320\300\1\x8C\101 386,SM @@ -542,14 +540,14 @@ MOV reg_eax,mem_offs \301\321\1\xA1\35 386,SM MOV mem_offs,reg_al \300\1\xA2\34 8086,SM MOV mem_offs,reg_ax \300\320\1\xA3\34 8086,SM MOV mem_offs,reg_eax \300\321\1\xA3\34 386,SM -MOV reg32,reg_cr4 \2\x0F\x20\204 PENT -MOV reg32,reg_creg \2\x0F\x20\101 386 -MOV reg32,reg_dreg \2\x0F\x21\101 386 -MOV reg32,reg_treg \2\x0F\x24\101 386 -MOV reg_cr4,reg32 \2\x0F\x22\214 PENT -MOV reg_creg,reg32 \2\x0F\x22\110 386 -MOV reg_dreg,reg32 \2\x0F\x23\110 386 -MOV reg_treg,reg32 \2\x0F\x26\110 386 +MOV reg32,reg_cr4 \2\x0F\x20\204 PENT,PRIV +MOV reg32,reg_creg \2\x0F\x20\101 386,PRIV +MOV reg32,reg_dreg \2\x0F\x21\101 386,PRIV +MOV reg32,reg_treg \2\x0F\x24\101 386,PRIV +MOV reg_cr4,reg32 \2\x0F\x22\214 PENT,PRIV +MOV reg_creg,reg32 \2\x0F\x22\110 386,PRIV +MOV reg_dreg,reg32 \2\x0F\x23\110 386,PRIV +MOV reg_treg,reg32 \2\x0F\x26\110 386,PRIV MOV mem,reg8 \300\1\x88\101 8086,SM MOV reg8,reg8 \300\1\x88\101 8086 MOV mem,reg16 \320\300\1\x89\101 8086,SM @@ -660,8 +658,8 @@ PANDN mmxreg,mem \301\2\x0F\xDF\110 PENT,MMX,SM PANDN mmxreg,mmxreg \2\x0F\xDF\110 PENT,MMX PAVEB mmxreg,mem \301\2\x0F\x50\110 PENT,MMX,SM,CYRIX PAVEB mmxreg,mmxreg \2\x0F\x50\110 PENT,MMX,CYRIX -PAVGUSB mmxreg,mem \301\2\x0F\x0F\110\01\xBF PENT,MMX,SM,FPU -PAVGUSB mmxreg,mmxreg \2\x0F\x0F\110\01\xBF PENT,MMX,FPU +PAVGUSB mmxreg,mem \301\2\x0F\x0F\110\01\xBF PENT,3DNOW,SM +PAVGUSB mmxreg,mmxreg \2\x0F\x0F\110\01\xBF PENT,3DNOW PCMPEQB mmxreg,mem \301\2\x0F\x74\110 PENT,MMX,SM PCMPEQB mmxreg,mmxreg \2\x0F\x74\110 PENT,MMX PCMPEQD mmxreg,mem \301\2\x0F\x76\110 PENT,MMX,SM @@ -675,40 +673,40 @@ PCMPGTD mmxreg,mmxreg \2\x0F\x66\110 PENT,MMX PCMPGTW mmxreg,mem \301\2\x0F\x65\110 PENT,MMX,SM PCMPGTW mmxreg,mmxreg \2\x0F\x65\110 PENT,MMX PDISTIB mmxreg,mem \301\2\x0F\x54\110 PENT,MMX,SM,CYRIX -PF2ID mmxreg,mem \301\2\x0F\x0F\110\01\x1D PENT,MMX,SM,FPU -PF2ID mmxreg,mmxreg \2\x0F\x0F\110\01\x1D PENT,MMX,FPU -PFACC mmxreg,mem \301\2\x0F\x0F\110\01\xAE PENT,MMX,SM,FPU -PFACC mmxreg,mmxreg \2\x0F\x0F\110\01\xAE PENT,MMX,FPU -PFADD mmxreg,mem \301\2\x0F\x0F\110\01\x9E PENT,MMX,SM,FPU -PFADD mmxreg,mmxreg \2\x0F\x0F\110\01\x9E PENT,MMX,FPU -PFCMPEQ mmxreg,mem \301\2\x0F\x0F\110\01\xB0 PENT,MMX,SM,FPU -PFCMPEQ mmxreg,mmxreg \2\x0F\x0F\110\01\xB0 PENT,MMX,FPU -PFCMPGE mmxreg,mem \301\2\x0F\x0F\110\01\x90 PENT,MMX,SM,FPU -PFCMPGE mmxreg,mmxreg \2\x0F\x0F\110\01\x90 PENT,MMX,FPU -PFCMPGT mmxreg,mem \301\2\x0F\x0F\110\01\xA0 PENT,MMX,SM,FPU -PFCMPGT mmxreg,mmxreg \2\x0F\x0F\110\01\xA0 PENT,MMX,FPU -PFMAX mmxreg,mem \301\2\x0F\x0F\110\01\xA4 PENT,MMX,SM,FPU -PFMAX mmxreg,mmxreg \2\x0F\x0F\110\01\xA4 PENT,MMX,FPU -PFMIN mmxreg,mem \301\2\x0F\x0F\110\01\x94 PENT,MMX,SM,FPU -PFMIN mmxreg,mmxreg \2\x0F\x0F\110\01\x94 PENT,MMX,FPU -PFMUL mmxreg,mem \301\2\x0F\x0F\110\01\xB4 PENT,MMX,SM,FPU -PFMUL mmxreg,mmxreg \2\x0F\x0F\110\01\xB4 PENT,MMX,FPU -PFRCP mmxreg,mem \301\2\x0F\x0F\110\01\x96 PENT,MMX,SM,FPU -PFRCP mmxreg,mmxreg \2\x0F\x0F\110\01\x96 PENT,MMX,FPU -PFRCPIT1 mmxreg,mem \301\2\x0F\x0F\110\01\xA6 PENT,MMX,SM,FPU -PFRCPIT1 mmxreg,mmxreg \2\x0F\x0F\110\01\xA6 PENT,MMX,FPU -PFRCPIT2 mmxreg,mem \301\2\x0F\x0F\110\01\xB6 PENT,MMX,SM,FPU -PFRCPIT2 mmxreg,mmxreg \2\x0F\x0F\110\01\xB6 PENT,MMX,FPU -PFRSQIT1 mmxreg,mem \301\2\x0F\x0F\110\01\xA7 PENT,MMX,SM,FPU -PFRSQIT1 mmxreg,mmxreg \2\x0F\x0F\110\01\xA7 PENT,MMX,FPU -PFRSQRT mmxreg,mem \301\2\x0F\x0F\110\01\x97 PENT,MMX,SM,FPU -PFRSQRT mmxreg,mmxreg \2\x0F\x0F\110\01\x97 PENT,MMX,FPU -PFSUB mmxreg,mem \301\2\x0F\x0F\110\01\x9A PENT,MMX,SM,FPU -PFSUB mmxreg,mmxreg \2\x0F\x0F\110\01\x9A PENT,MMX,FPU -PFSUBR mmxreg,mem \301\2\x0F\x0F\110\01\xAA PENT,MMX,SM,FPU -PFSUBR mmxreg,mmxreg \2\x0F\x0F\110\01\xAA PENT,MMX,FPU -PI2FD mmxreg,mem \301\2\x0F\x0F\110\01\x0D PENT,MMX,SM,FPU -PI2FD mmxreg,mmxreg \2\x0F\x0F\110\01\x0D PENT,MMX,FPU +PF2ID mmxreg,mem \301\2\x0F\x0F\110\01\x1D PENT,3DNOW,SM +PF2ID mmxreg,mmxreg \2\x0F\x0F\110\01\x1D PENT,3DNOW +PFACC mmxreg,mem \301\2\x0F\x0F\110\01\xAE PENT,3DNOW,SM +PFACC mmxreg,mmxreg \2\x0F\x0F\110\01\xAE PENT,3DNOW +PFADD mmxreg,mem \301\2\x0F\x0F\110\01\x9E PENT,3DNOW,SM +PFADD mmxreg,mmxreg \2\x0F\x0F\110\01\x9E PENT,3DNOW +PFCMPEQ mmxreg,mem \301\2\x0F\x0F\110\01\xB0 PENT,3DNOW,SM +PFCMPEQ mmxreg,mmxreg \2\x0F\x0F\110\01\xB0 PENT,3DNOW +PFCMPGE mmxreg,mem \301\2\x0F\x0F\110\01\x90 PENT,3DNOW,SM +PFCMPGE mmxreg,mmxreg \2\x0F\x0F\110\01\x90 PENT,3DNOW +PFCMPGT mmxreg,mem \301\2\x0F\x0F\110\01\xA0 PENT,3DNOW,SM +PFCMPGT mmxreg,mmxreg \2\x0F\x0F\110\01\xA0 PENT,3DNOW +PFMAX mmxreg,mem \301\2\x0F\x0F\110\01\xA4 PENT,3DNOW,SM +PFMAX mmxreg,mmxreg \2\x0F\x0F\110\01\xA4 PENT,3DNOW +PFMIN mmxreg,mem \301\2\x0F\x0F\110\01\x94 PENT,3DNOW,SM +PFMIN mmxreg,mmxreg \2\x0F\x0F\110\01\x94 PENT,3DNOW +PFMUL mmxreg,mem \301\2\x0F\x0F\110\01\xB4 PENT,3DNOW,SM +PFMUL mmxreg,mmxreg \2\x0F\x0F\110\01\xB4 PENT,3DNOW +PFRCP mmxreg,mem \301\2\x0F\x0F\110\01\x96 PENT,3DNOW,SM +PFRCP mmxreg,mmxreg \2\x0F\x0F\110\01\x96 PENT,3DNOW +PFRCPIT1 mmxreg,mem \301\2\x0F\x0F\110\01\xA6 PENT,3DNOW,SM +PFRCPIT1 mmxreg,mmxreg \2\x0F\x0F\110\01\xA6 PENT,3DNOW +PFRCPIT2 mmxreg,mem \301\2\x0F\x0F\110\01\xB6 PENT,3DNOW,SM +PFRCPIT2 mmxreg,mmxreg \2\x0F\x0F\110\01\xB6 PENT,3DNOW +PFRSQIT1 mmxreg,mem \301\2\x0F\x0F\110\01\xA7 PENT,3DNOW,SM +PFRSQIT1 mmxreg,mmxreg \2\x0F\x0F\110\01\xA7 PENT,3DNOW +PFRSQRT mmxreg,mem \301\2\x0F\x0F\110\01\x97 PENT,3DNOW,SM +PFRSQRT mmxreg,mmxreg \2\x0F\x0F\110\01\x97 PENT,3DNOW +PFSUB mmxreg,mem \301\2\x0F\x0F\110\01\x9A PENT,3DNOW,SM +PFSUB mmxreg,mmxreg \2\x0F\x0F\110\01\x9A PENT,3DNOW +PFSUBR mmxreg,mem \301\2\x0F\x0F\110\01\xAA PENT,3DNOW,SM +PFSUBR mmxreg,mmxreg \2\x0F\x0F\110\01\xAA PENT,3DNOW +PI2FD mmxreg,mem \301\2\x0F\x0F\110\01\x0D PENT,3DNOW,SM +PI2FD mmxreg,mmxreg \2\x0F\x0F\110\01\x0D PENT,3DNOW PMACHRIW mmxreg,mem \301\2\x0F\x5E\110 PENT,MMX,SM,CYRIX PMADDWD mmxreg,mem \301\2\x0F\xF5\110 PENT,MMX,SM PMADDWD mmxreg,mmxreg \2\x0F\xF5\110 PENT,MMX @@ -716,8 +714,8 @@ PMAGW mmxreg,mem \301\2\x0F\x52\110 PENT,MMX,SM,CYRIX PMAGW mmxreg,mmxreg \2\x0F\x52\110 PENT,MMX,CYRIX PMULHRIW mmxreg,mem \301\2\x0F\x5D\110 PENT,MMX,SM,CYRIX PMULHRIW mmxreg,mmxreg \2\x0F\x5D\110 PENT,MMX,CYRIX -PMULHRWA mmxreg,mem \301\2\x0F\x0F\110\1\xB7 PENT,MMX,SM,FPU -PMULHRWA mmxreg,mmxreg \2\x0F\x0F\110\1\xB7 PENT,MMX,FPU +PMULHRWA mmxreg,mem \301\2\x0F\x0F\110\1\xB7 PENT,3DNOW,SM +PMULHRWA mmxreg,mmxreg \2\x0F\x0F\110\1\xB7 PENT,3DNOW PMULHRWC mmxreg,mem \301\2\x0F\x59\110 PENT,MMX,SM,CYRIX PMULHRWC mmxreg,mmxreg \2\x0F\x59\110 PENT,MMX,CYRIX PMULHW mmxreg,mem \301\2\x0F\xE5\110 PENT,MMX,SM @@ -743,8 +741,8 @@ POPFD void \321\1\x9D 386 POPFW void \320\1\x9D 186 POR mmxreg,mem \301\2\x0F\xEB\110 PENT,MMX,SM POR mmxreg,mmxreg \2\x0F\xEB\110 PENT,MMX -PREFETCH mem \2\x0F\x0D\200 PENT,MMX,SM,FPU -PREFETCHW mem \2\x0F\x0D\201 PENT,MMX,SM,FPU +PREFETCH mem \2\x0F\x0D\200 PENT,3DNOW,SM +PREFETCHW mem \2\x0F\x0D\201 PENT,3DNOW,SM PSLLD mmxreg,mem \301\2\x0F\xF2\110 PENT,MMX,SM PSLLD mmxreg,mmxreg \2\x0F\xF2\110 PENT,MMX PSLLD mmxreg,imm \2\x0F\x72\206\25 PENT,MMX @@ -832,7 +830,8 @@ RCR rm16,imm \320\300\1\xC1\203\25 186,SB RCR rm32,unity \321\300\1\xD1\203 386 RCR rm32,reg_cl \321\300\1\xD3\203 386 RCR rm32,imm \321\300\1\xC1\203\25 386,SB -RDMSR void \2\x0F\x32 PENT +RDSHR void \2\x0F\x36 P6,CYRIX,SMM +RDMSR void \2\x0F\x32 PENT,PRIV RDPMC void \2\x0F\x33 P6 RDTSC void \2\x0F\x31 PENT RESB imm \340 8086 @@ -864,7 +863,9 @@ ROR rm16,imm \320\300\1\xC1\201\25 186,SB ROR rm32,unity \321\300\1\xD1\201 386 ROR rm32,reg_cl \321\300\1\xD3\201 386 ROR rm32,imm \321\300\1\xC1\201\25 386,SB -RSM void \2\x0F\xAA PENT +RSDC reg_sreg,mem80 \2\x0F\x79\101 486,CYRIX,SMM +RSLDT mem80 \2\x0F\x7B\200 486,CYRIX,SMM +RSM void \2\x0F\xAA PENT,SMM SAHF void \1\x9E 8086 SAL rm8,unity \300\1\xD0\204 8086,ND SAL rm8,reg_cl \300\1\xD2\204 8086,ND @@ -911,7 +912,7 @@ SBB mem,imm32 \321\300\1\x81\203\41 386,SM SCASB void \1\xAE 8086 SCASD void \321\1\xAF 386 SCASW void \320\1\xAF 8086 -SGDT mem \300\2\x0F\x01\200 286,PRIV +SGDT mem \300\2\x0F\x01\200 286 SHL rm8,unity \300\1\xD0\204 8086 SHL rm8,reg_cl \300\1\xD2\204 8086 SHL rm8,imm \300\1\xC0\204\25 186,SB @@ -946,23 +947,26 @@ SHRD mem,reg16,reg_cl \300\320\2\x0F\xAD\101 386,SM SHRD reg16,reg16,reg_cl \300\320\2\x0F\xAD\101 386 SHRD mem,reg32,reg_cl \300\321\2\x0F\xAD\101 386,SM SHRD reg32,reg32,reg_cl \300\321\2\x0F\xAD\101 386 -SIDT mem \300\2\x0F\x01\201 286,PRIV -SLDT mem \300\1\x0F\17\200 286,PRIV -SLDT mem16 \300\1\x0F\17\200 286,PRIV -SLDT reg16 \300\1\x0F\17\200 286,PRIV +SIDT mem \300\2\x0F\x01\201 286 +SLDT mem \300\1\x0F\17\200 286 +SLDT mem16 \300\1\x0F\17\200 286 +SLDT reg16 \300\1\x0F\17\200 286 SMI void \1\xF1 386,UNDOC -SMSW mem \300\2\x0F\x01\204 286,PRIV -SMSW mem16 \300\2\x0F\x01\204 286,PRIV -SMSW reg16 \300\2\x0F\x01\204 286,PRIV +SMINT void \2\x0F\x38 P6,CYRIX +; Older Cyrix chips had this; they had to move due to conflict with MMX +SMINTOLD void \2\x0F\x7E 486,CYRIX +SMSW mem \300\2\x0F\x01\204 286 +SMSW mem16 \300\2\x0F\x01\204 286 +SMSW reg16 \300\2\x0F\x01\204 286 STC void \1\xF9 8086 STD void \1\xFD 8086 STI void \1\xFB 8086 STOSB void \1\xAA 8086 STOSD void \321\1\xAB 386 STOSW void \320\1\xAB 8086 -STR mem \300\1\x0F\17\201 286,PRIV -STR mem16 \300\1\x0F\17\201 286,PRIV -STR reg16 \300\1\x0F\17\201 286,PRIV +STR mem \300\1\x0F\17\201 286,PROT +STR mem16 \300\1\x0F\17\201 286,PROT +STR reg16 \300\1\x0F\17\201 286,PROT SUB mem,reg8 \300\1\x28\101 8086,SM SUB reg8,reg8 \300\1\x28\101 8086 SUB mem,reg16 \320\300\1\x29\101 8086,SM @@ -986,8 +990,13 @@ SUB rm32,imm \321\300\1\x81\205\41 386,SM SUB mem,imm8 \300\1\x80\205\21 8086,SM SUB mem,imm16 \320\300\1\x81\205\31 8086,SM SUB mem,imm32 \321\300\1\x81\205\41 386,SM +SVDC mem80,reg_sreg \2\x0F\x78\101 486,CYRIX,SMM +SVLDT mem80 \2\x0F\x7A\200 486,CYRIX,SMM +SVTS mem80 \2\x0F\x7C\200 486,CYRIX,SMM +SYSCALL void \2\x0F\x05 P6,AMD SYSENTER void \2\x0F\x34 P6 SYSEXIT void \2\x0F\x36 P6,PRIV +SYSRET void \2\x0F\x07 P6,PRIV,AMD TEST mem,reg8 \300\1\x84\101 8086,SM TEST reg8,reg8 \300\1\x84\101 8086 TEST mem,reg16 \320\300\1\x85\101 8086,SM @@ -1020,15 +1029,16 @@ UMOV reg16,mem \320\301\2\x0F\x13\110 386,UNDOC,SM UMOV reg16,reg16 \320\301\2\x0F\x13\110 386,UNDOC UMOV reg32,mem \321\301\2\x0F\x13\110 386,UNDOC,SM UMOV reg32,reg32 \321\301\2\x0F\x13\110 386,UNDOC -VERR mem \300\1\x0F\17\204 286,PRIV -VERR mem16 \300\1\x0F\17\204 286,PRIV -VERR reg16 \300\1\x0F\17\204 286,PRIV -VERW mem \300\1\x0F\17\205 286,PRIV -VERW mem16 \300\1\x0F\17\205 286,PRIV -VERW reg16 \300\1\x0F\17\205 286,PRIV +VERR mem \300\1\x0F\17\204 286,PROT +VERR mem16 \300\1\x0F\17\204 286,PROT +VERR reg16 \300\1\x0F\17\204 286,PROT +VERW mem \300\1\x0F\17\205 286,PROT +VERW mem16 \300\1\x0F\17\205 286,PROT +VERW reg16 \300\1\x0F\17\205 286,PROT WAIT void \1\x9B 8086 -WBINVD void \2\x0F\x09 486 -WRMSR void \2\x0F\x30 PENT +WBINVD void \2\x0F\x09 486,PRIV +WRSHR void \2\x0F\x37 P6,CYRIX,SMM +WRMSR void \2\x0F\x30 PENT,PRIV XADD mem,reg8 \300\2\x0F\xC0\101 486,SM XADD reg8,reg8 \300\2\x0F\xC0\101 486 XADD mem,reg16 \320\300\2\x0F\xC1\101 486,SM @@ -1088,3 +1098,196 @@ Jcc imm \330\x70\50 8086 Jcc imm|short \330\x70\50 8086 SETcc mem \300\1\x0F\330\x90\200 386,SB SETcc reg8 \300\1\x0F\330\x90\200 386 + +; Katmai Streaming SIMD instructions (SSE -- a.k.a. KNI, XMM, MMX2) +ADDPS xmmreg,xmmreg \2\x0F\x58\110 KATMAI,SSE +ADDPS xmmreg,mem \301\2\x0F\x58\110 KATMAI,SSE +ADDSS xmmreg,xmmreg \3\xF3\x0F\x58\110 KATMAI,SSE +ADDSS xmmreg,mem \301\3\xF3\x0F\x58\110 KATMAI,SSE + +MULPS xmmreg,xmmreg \2\x0F\x59\110 KATMAI,SSE +MULPS xmmreg,mem \301\2\x0F\x59\110 KATMAI,SSE +MULSS xmmreg,xmmreg \3\xF3\x0F\x59\110 KATMAI,SSE +MULSS xmmreg,mem \301\3\xF3\x0F\x59\110 KATMAI,SSE + +DIVPS xmmreg,xmmreg \2\x0F\x5E\110 KATMAI,SSE +DIVPS xmmreg,mem \301\2\x0F\x5E\110 KATMAI,SSE +DIVSS xmmreg,xmmreg \3\xF3\x0F\x5E\110 KATMAI,SSE +DIVSS xmmreg,mem \301\3\xF3\x0F\x5E\110 KATMAI,SSE + +SUBPS xmmreg,xmmreg \2\x0F\x5C\110 KATMAI,SSE +SUBPS xmmreg,mem \301\2\x0F\x5C\110 KATMAI,SSE +SUBSS xmmreg,xmmreg \3\xF3\x0F\x5C\110 KATMAI,SSE +SUBSS xmmreg,mem \301\3\xF3\x0F\x5C\110 KATMAI,SSE + +RCPPS xmmreg,xmmreg \2\x0F\x53\110 KATMAI,SSE +RCPPS xmmreg,mem \301\2\x0F\x53\110 KATMAI,SSE +RCPSS xmmreg,xmmreg \3\xF3\x0F\x53\110 KATMAI,SSE +RCPSS xmmreg,mem \301\3\xF3\x0F\x53\110 KATMAI,SSE + +RSQRTPS xmmreg,xmmreg \2\x0F\x52\110 KATMAI,SSE +RSQRTPS xmmreg,mem \301\2\x0F\x52\110 KATMAI,SSE +RSQRTSS xmmreg,xmmreg \3\xF3\x0F\x52\110 KATMAI,SSE +RSQRTSS xmmreg,mem \301\3\xF3\x0F\x52\110 KATMAI,SSE + +SQRTPS xmmreg,xmmreg \2\x0F\x51\110 KATMAI,SSE +SQRTPS xmmreg,mem \301\2\x0F\x51\110 KATMAI,SSE +SQRTSS xmmreg,xmmreg \3\xF3\x0F\x51\110 KATMAI,SSE +SQRTSS xmmreg,mem \301\3\xF3\x0F\x51\110 KATMAI,SSE + +ANDPS xmmreg,xmmreg \2\x0F\x54\110 KATMAI,SSE +ANDPS xmmreg,mem \301\2\x0F\x54\110 KATMAI,SSE +ANDNPS xmmreg,xmmreg \2\x0F\x55\110 KATMAI,SSE +ANDNPS xmmreg,mem \301\2\x0F\x55\110 KATMAI,SSE +ORPS xmmreg,xmmreg \2\x0F\x56\110 KATMAI,SSE +ORPS xmmreg,mem \301\2\x0F\x56\110 KATMAI,SSE +XORPS xmmreg,xmmreg \2\x0F\x57\110 KATMAI,SSE +XORPS xmmreg,mem \301\2\x0F\x57\110 KATMAI,SSE + +MAXPS xmmreg,xmmreg \2\x0F\x5F\110 KATMAI,SSE +MAXPS xmmreg,mem \301\2\x0F\x5F\110 KATMAI,SSE +MAXSS xmmreg,xmmreg \3\xF3\x0F\x5F\110 KATMAI,SSE +MAXSS xmmreg,mem \301\3\xF3\x0F\x5F\110 KATMAI,SSE +MINPS xmmreg,xmmreg \2\x0F\x5D\110 KATMAI,SSE +MINPS xmmreg,mem \301\2\x0F\x5D\110 KATMAI,SSE +MINSS xmmreg,xmmreg \3\xF3\x0F\x5D\110 KATMAI,SSE +MINSS xmmreg,mem \301\3\xF3\x0F\x5D\110 KATMAI,SSE + +CMPEQPS xmmreg,xmmreg \2\x0F\xC2\110\1\x00 KATMAI,SSE +CMPEQPS xmmreg,mem \301\2\x0F\xC2\110\1\x00 KATMAI,SSE +CMPEQSS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x00 KATMAI,SSE +CMPEQSS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\0x00 KATMAI,SSE + +CMPLTPS xmmreg,xmmreg \2\x0F\xC2\110\1\x01 KATMAI,SSE +CMPLTPS xmmreg,mem \301\2\x0F\xC2\110\1\x01 KATMAI,SSE +CMPLTSS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x01 KATMAI,SSE +CMPLTSS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\x01 KATMAI,SSE + +CMPLEPS xmmreg,xmmreg \2\x0F\xC2\110\1\x02 KATMAI,SSE +CMPLEPS xmmreg,mem \301\2\x0F\xC2\110\1\x02 KATMAI,SSE +CMPLESS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x02 KATMAI,SSE +CMPLESS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\x02 KATMAI,SSE + +CMPUNORDPS xmmreg,xmmreg \2\x0F\xC2\110\1\x03 KATMAI,SSE +CMPUNORDPS xmmreg,mem \301\2\x0F\xC2\110\1\x03 KATMAI,SSE +CMPUNORDSS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x03 KATMAI,SSE +CMPUNORDSS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\x03 KATMAI,SSE + +CMPNEQPS xmmreg,xmmreg \2\x0F\xC2\110\1\x04 KATMAI,SSE +CMPNEQPS xmmreg,mem \301\2\x0F\xC2\110\1\x04 KATMAI,SSE +CMPNEQSS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x04 KATMAI,SSE +CMPNEQSS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\x04 KATMAI,SSE + +CMPNLTPS xmmreg,xmmreg \2\x0F\xC2\110\1\x05 KATMAI,SSE +CMPNLTPS xmmreg,mem \301\2\x0F\xC2\110\1\x05 KATMAI,SSE +CMPNLTSS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x05 KATMAI,SSE +CMPNLTSS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\x05 KATMAI,SSE + +CMPNLEPS xmmreg,xmmreg \2\x0F\xC2\110\1\x06 KATMAI,SSE +CMPNLEPS xmmreg,mem \301\2\x0F\xC2\110\1\x06 KATMAI,SSE +CMPNLESS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x06 KATMAI,SSE +CMPNLESS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\x06 KATMAI,SSE + +CMPORDPS xmmreg,xmmreg \2\x0F\xC2\110\1\x07 KATMAI,SSE +CMPORDPS xmmreg,mem \301\2\x0F\xC2\110\1\x07 KATMAI,SSE +CMPORDSS xmmreg,xmmreg \3\xF3\x0F\xC2\110\1\x07 KATMAI,SSE +CMPORDSS xmmreg,mem \301\3\xF3\x0F\xC2\110\1\x07 KATMAI,SSE + +UCOMISS xmmreg,xmmreg \2\x0F\x2E\110 KATMAI,SSE +UCOMISS xmmreg,mem \301\2\x0F\x2E\110 KATMAI,SSE +COMISS xmmreg,xmmreg \2\x0F\x2F\110 KATMAI,SSE +COMISS xmmreg,mem \301\2\x0F\x2F\110 KATMAI,SSE + +CVTPI2PS xmmreg,mmxreg \2\x0F\x2A\110 KATMAI,SSE,MMX +CVTPI2PS xmmreg,mem \301\2\x0F\x2A\110 KATMAI,SSE,MMX +CVTPS2PI mmxreg,xmmreg \2\x0F\x2D\110 KATMAI,SSE,MMX +CVTPS2PI mmxreg,mem \301\2\x0F\x2D\110 KATMAI,SSE,MMX +CVTTPS2PI mmxreg,xmmreg \2\x0F\x2C\110 KATMAI,SSE,MMX +CVTTPS2PI mmxreg,mem \301\2\x0F\x2C\110 KATMAI,SSE,MMX + +CVTSI2SS xmmreg,reg32 \3\xF3\x0F\x2A\110 KATMAI,SSE +CVTSI2SS xmmreg,mem \301\3\xF3\x0F\x2A\110 KATMAI,SSE +CVTSS2SI reg32,xmmreg \3\xF3\x0F\x2D\110 KATMAI,SSE +CVTSS2SI reg32,mem \301\3\xF3\x0F\x2D\110 KATMAI,SSE +CVTTSS2SI reg32,xmmreg \3\xF3\x0F\x2C\110 KATMAI,SSE +CVTTSS2SI reg32,mem \301\xF3\3\x0F\x2C\110 KATMAI,SSE + +; FXSAVE/FXRSTOR were introduced in Deschutes +FXSAVE mem \300\2\x0F\xAE\200 P6,SSE,FPU +FXRSTOR mem \300\2\x0F\xAE\201 P6,SSE,FPU +LDMXCSR mem \300\2\x0F\xAE\202 KATMAI,SSE +STMXCSR mem \300\2\x0F\xAE\203 KATMAI,SSE + +; These instructions aren't SSE-specific; they are generic memory operations +; and work even if CR4.OSFXFR == 0 +SFENCE void \3\x0F\xAE\xF8 KATMAI + +PREFETCHNTA mem \300\2\x0F\x18\200 KATMAI,SM +PREFETCHT0 mem \300\2\x0F\x18\201 KATMAI,SM +PREFETCHT1 mem \300\2\x0F\x18\202 KATMAI,SM +PREFETCHT2 mem \300\2\x0F\x18\203 KATMAI,SM + +MOVAPS xmmreg,xmmreg \2\x0F\x28\110 KATMAI,SSE +MOVAPS xmmreg,mem \301\2\x0F\x28\110 KATMAI,SSE +MOVAPS xmmreg,xmmreg \2\x0F\x29\101 KATMAI,SSE +MOVAPS mem,xmmreg \300\2\x0F\x29\101 KATMAI,SSE + +MOVHPS xmmreg,xmmreg \2\x0F\x16\110 KATMAI,SSE +MOVHPS xmmreg,mem \301\2\x0F\x16\110 KATMAI,SSE +MOVHPS xmmreg,xmmreg \2\x0F\x17\101 KATMAI,SSE +MOVHPS mem,xmmreg \300\2\x0F\x17\101 KATMAI,SSE + +MOVLPS xmmreg,xmmreg \2\x0F\x12\110 KATMAI,SSE +MOVLPS xmmreg,mem \301\2\x0F\x12\110 KATMAI,SSE +MOVLPS xmmreg,xmmreg \2\x0F\x13\101 KATMAI,SSE +MOVLPS mem,xmmreg \300\2\x0F\x13\101 KATMAI,SSE + +MOVUPS xmmreg,xmmreg \2\x0F\x10\110 KATMAI,SSE +MOVUPS xmmreg,mem \301\2\x0F\x10\110 KATMAI,SSE +MOVUPS xmmreg,xmmreg \2\x0F\x11\101 KATMAI,SSE +MOVUPS mem,xmmreg \300\2\x0F\x11\101 KATMAI,SSE + +MOVSS xmmreg,xmmreg \3\xF3\x0F\x10\110 KATMAI,SSE +MOVSS xmmreg,mem \301\3\xF3\x0F\x10\110 KATMAI,SSE +MOVSS xmmreg,xmmreg \3\xF3\x0F\x11\101 KATMAI,SSE +MOVSS mem,xmmreg \300\3\xF3\x0F\x11\101 KATMAI,SSE + +MOVMSKPS reg32,xmmreg \2\x0F\x50\110 KATMAI,SSE + +MOVNTPS mem,xmmreg \2\x0F\x2B\101 KATMAI,SSE + +SHUFPS xmmreg,xmmreg,imm8 \2\x0F\xC6\110\22 KATMAI,SSE +SHUFPS xmmreg,mem,imm8 \301\2\x0F\xC6\110\22 KATMAI,SSE + +UNPCKHPS xmmreg,xmmreg \2\x0F\x15\110 KATMAI,SSE +UNPCKHPS xmmreg,mem \301\2\x0F\x15\110 KATMAI,SSE +UNPCKLPS xmmreg,xmmreg \2\x0F\x14\110 KATMAI,SSE +UNPCKLPS xmmreg,mem \301\2\x0F\x14\110 KATMAI,SSE + +; New MMX instructions introduced in Katmai +MOVNTQ mem,mmxreg \2\x0F\xE7\101 KATMAI,MMX,SM +PAVGB mmxreg,mmxreg \2\x0F\xE0\110 KATMAI,MMX +PAVGB mmxreg,mem \301\2\x0F\xE0\110 KATMAI,MMX,SM +PAVGW mmxreg,mmxreg \2\x0F\xE3\110 KATMAI,MMX +PAVGW mmxreg,mem \301\2\x0F\xE3\110 KATMAI,MMX,SM +PEXTRW reg32,mmxreg,imm8 \2\x0F\xC5\110\22 KATMAI,MMX +; This is documented as using a reg32, but it's really using only 16 bits -- accept either +PINSRW mmxreg,reg16,imm8 \2\x0F\xC4\110\22 KATMAI,MMX +PINSRW mmxreg,reg32,imm8 \2\x0F\xC4\110\22 KATMAI,MMX +PINSRW mmxreg,mem16,imm8 \301\2\x0F\xC4\110\22 KATMAI,MMX,SM +PMAXSW mmxreg,mmxreg \2\x0F\xEE\110 KATMAI,MMX +PMAXSW mmxreg,mem \301\2\x0F\xEE\110 KATMAI,MMX,SM +PMAXUB mmxreg,mmxreg \2\x0F\xDE\110 KATMAI,MMX +PMAXUB mmxreg,mem \301\2\x0F\xDE\110 KATMAI,MMX,SM +PMINSW mmxreg,mmxreg \2\x0F\xEA\110 KATMAI,MMX +PMINSW mmxreg,mem \301\2\x0F\xEA\110 KATMAI,MMX,SM +PMINUB mmxreg,mmxreg \2\x0F\xDA\110 KATMAI,MMX +PMINUB mmxreg,mem \301\2\x0F\xDA\110 KATMAI,MMX,SM +PMOVMSKB reg32,mmxreg \2\x0F\xD7\110 KATMAI,MMX +PMULHUW mmxreg,mmxreg \2\x0F\xE4\110 KATMAI,MMX +PMULHUW mmxreg,mem \301\2\x0F\xE4\110 KATMAI,MMX,SM +PSADBW mmxreg,mmxreg \2\x0F\xF6\110 KATMAI,MMX +PSADBW mmxreg,mem \301\2\x0F\xF6\110 KATMAI,MMX,SM +PSHUFW mmxreg,mmxreg,imm8 \2\x0F\x70\110\22 KATMAI,MMX +PSHUFW mmxreg,mem,imm8 \301\2\x0F\x70\110\22 KATMAI,MMX,SM +MASKMOVQ mmxreg,mmxreg \2\x0F\xF7\110 KATMAI,MMX diff --git a/insns.h b/insns.h index 1b637fc5..f12ea60c 100644 --- a/insns.h +++ b/insns.h @@ -14,7 +14,7 @@ struct itemplate { int operands; /* number of operands */ long opd[3]; /* bit flags for operand types */ char *code; /* the code it assembles to */ - int flags; /* some flags */ + unsigned long flags; /* some flags */ }; /* @@ -44,23 +44,30 @@ struct itemplate { * required to have unspecified size in the instruction too...) */ -#define IF_SM 0x0001 /* size match */ -#define IF_SM2 0x0002 /* size match first two operands */ -#define IF_SB 0x0004 /* unsized operands can't be non-byte */ -#define IF_SW 0x0008 /* unsized operands can't be non-word */ -#define IF_SD 0x0010 /* unsized operands can't be nondword */ -#define IF_8086 0x0000 /* 8086 instruction */ -#define IF_186 0x0100 /* 186+ instruction */ -#define IF_286 0x0200 /* 286+ instruction */ -#define IF_386 0x0300 /* 386+ instruction */ -#define IF_486 0x0400 /* 486+ instruction */ -#define IF_PENT 0x0500 /* Pentium instruction */ -#define IF_P6 0x0600 /* P6 instruction */ -#define IF_CYRIX 0x0800 /* Cyrix-specific instruction */ -#define IF_PMASK 0x0F00 /* the mask for processor types */ -#define IF_PRIV 0x1000 /* it's a privileged instruction */ -#define IF_UNDOC 0x2000 /* it's an undocumented instruction */ -#define IF_FPU 0x4000 /* it's an FPU instruction */ -#define IF_MMX 0x8000 /* it's an MMX instruction */ +#define IF_SM 0x00000001UL /* size match */ +#define IF_SM2 0x00000002UL /* size match first two operands */ +#define IF_SB 0x00000004UL /* unsized operands can't be non-byte */ +#define IF_SW 0x00000008UL /* unsized operands can't be non-word */ +#define IF_SD 0x00000010UL /* unsized operands can't be nondword */ +#define IF_PRIV 0x00000100UL /* it's a privileged instruction */ +#define IF_SMM 0x00000200UL /* it's only valid in SMM */ +#define IF_PROT 0x00000400UL /* it's protected mode only */ +#define IF_UNDOC 0x00001000UL /* it's an undocumented instruction */ +#define IF_FPU 0x00002000UL /* it's an FPU instruction */ +#define IF_MMX 0x00004000UL /* it's an MMX instruction */ +#define IF_3DNOW 0x00008000UL /* it's a 3DNow! instruction */ +#define IF_SSE 0x00010000UL /* it's a SSE (KNI, MMX2) instruction */ +#define IF_PMASK 0xFF000000UL /* the mask for processor types */ +#define IF_PFMASK 0xF001FF00UL /* the mask for disassembly "prefer" */ +#define IF_8086 0x00000000UL /* 8086 instruction */ +#define IF_186 0x01000000UL /* 186+ instruction */ +#define IF_286 0x02000000UL /* 286+ instruction */ +#define IF_386 0x03000000UL /* 386+ instruction */ +#define IF_486 0x04000000UL /* 486+ instruction */ +#define IF_PENT 0x05000000UL /* Pentium instruction */ +#define IF_P6 0x06000000UL /* P6 instruction */ +#define IF_KATMAI 0x07000000UL /* Katmai instructions */ +#define IF_CYRIX 0x10000000UL /* Cyrix-specific instruction */ +#define IF_AMD 0x20000000UL /* AMD-specific instruction */ #endif diff --git a/names.c b/names.c index 1a462ecf..e220ebfe 100644 --- a/names.c +++ b/names.c @@ -14,7 +14,8 @@ static char *reg_names[] = { /* register names, as strings */ "ebx", "ecx", "edi", "edx", "es", "esi", "esp", "fs", "gs", "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", "si", "sp", "ss", "st0", "st1", "st2", "st3", "st4", "st5", "st6", - "st7", "tr3", "tr4", "tr5", "tr6", "tr7" + "st7", "tr3", "tr4", "tr5", "tr6", "tr7", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7" }; static char *conditions[] = { /* condition code names */ diff --git a/nasm.h b/nasm.h index 4076284d..73a3fd90 100644 --- a/nasm.h +++ b/nasm.h @@ -13,7 +13,7 @@ #define NASM_MAJOR_VER 0 #define NASM_MINOR_VER 98 -#define NASM_VER "0.98 pre-release 3.4" +#define NASM_VER "0.98 pre-release 3.5" #ifndef NULL #define NULL 0 @@ -380,6 +380,7 @@ enum { #define REG16 0x00201002L #define REG32 0x00201004L #define MMXREG 0x00201008L /* MMX registers */ +#define XMMREG 0x00201010L /* XMM Katmai reg */ #define FPUREG 0x01000000L /* floating point stack registers */ #define FPU0 0x01000800L /* FPU stack register zero */ @@ -423,7 +424,8 @@ enum { /* register names */ R_EBP, R_EBX, R_ECX, R_EDI, R_EDX, R_ES, R_ESI, R_ESP, R_FS, R_GS, R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7, R_SI, R_SP, R_SS, R_ST0, R_ST1, R_ST2, R_ST3, R_ST4, R_ST5, - R_ST6, R_ST7, R_TR3, R_TR4, R_TR5, R_TR6, R_TR7, REG_ENUM_LIMIT + R_ST6, R_ST7, R_TR3, R_TR4, R_TR5, R_TR6, R_TR7, + R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7, REG_ENUM_LIMIT }; /* Instruction names automatically generated from insns.dat */ diff --git a/ndisasm.c b/ndisasm.c index a07a2781..99e943af 100644 --- a/ndisasm.c +++ b/ndisasm.c @@ -12,6 +12,7 @@ #include #include +#include "insns.h" #include "nasm.h" #include "nasmlib.h" #include "sync.h" @@ -21,14 +22,15 @@ static const char *help = "usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n" -" [-e bytes] [-k start,bytes] file\n" +" [-e bytes] [-k start,bytes] [-p vendor] file\n" " -a or -i activates auto (intelligent) sync\n" " -u sets USE32 (32-bit mode)\n" " -b 16 or -b 32 sets number of bits too\n" " -h displays this text\n" " -r displays the version number\n" " -e skips bytes of header\n" -" -k avoids disassembling bytes from position \n"; +" -k avoids disassembling bytes from position \n" +" -p selects the preferred vendor instruction set (intel, amd, cyrix)\n"; static void output_ins (unsigned long, unsigned char *, int, char *); static void skip (unsigned long dist, FILE *fp); @@ -44,6 +46,7 @@ int main(int argc, char **argv) int autosync = FALSE; int bits = 16; int eof = FALSE; + unsigned long prefer = 0; int rn_error; long offset; FILE *fp; @@ -157,6 +160,24 @@ int main(int argc, char **argv) add_sync (nextsync, synclen); p = ""; /* force to next argument */ break; + case 'p': /* preferred vendor */ + v = p[1] ? p+1 : --argc ? *++argv : NULL; + if (!v) { + fprintf(stderr, "%s: `-p' requires an argument\n", pname); + return 1; + } + if ( !strcmp(v, "intel") ) { + prefer = 0; /* Default */ + } else if ( !strcmp(v, "amd") ) { + prefer = IF_AMD|IF_3DNOW; + } else if ( !strcmp(v, "cyrix") ) { + prefer = IF_CYRIX|IF_3DNOW; + } else { + fprintf(stderr, "%s: unknown vendor `%s' specified with `-p'\n", pname, v); + return 1; + } + p = ""; /* force to next argument */ + break; } } else if (!filename) { filename = p; @@ -213,7 +234,7 @@ int main(int argc, char **argv) nextsync = next_sync (offset, &synclen); } while (p > q && (p - q >= INSN_MAX || lenread == 0)) { - lendis = disasm (q, outbuf, bits, offset, autosync); + lendis = disasm (q, outbuf, bits, offset, autosync, prefer); if (!lendis || lendis > (p - q) || lendis > nextsync-offset) lendis = eatbyte (q, outbuf); diff --git a/parser.c b/parser.c index 704e2eb4..1a9c9e4e 100644 --- a/parser.c +++ b/parser.c @@ -28,7 +28,8 @@ static long reg_flags[] = { /* sizes and special flags */ MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, MMXREG, REG16, REG16, REG_DESS, FPU0, FPUREG, FPUREG, FPUREG, FPUREG, FPUREG, FPUREG, FPUREG, REG_TREG, REG_TREG, REG_TREG, REG_TREG, - REG_TREG + REG_TREG, + XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG, XMMREG }; enum { /* special tokens */ diff --git a/preproc.c b/preproc.c index e16432a5..44609075 100644 --- a/preproc.c +++ b/preproc.c @@ -8,10 +8,30 @@ * initial version 18/iii/97 by Simon Tatham */ -#define br0 '{' -#define br1 "{" -#define br2 '}' -#define br3 "}" +/* Typical flow of text through preproc + * + * pp_getline gets tokenised lines, either + * + * from a macro expansion + * + * or + * { + * read_line gets raw text from stdmacpos, or predef, or current input file + * tokenise converts to tokens + * } + * + * expand_mmac_params is used to expand %1 etc., unless a macro is being + * defined or a false conditional is being processed + * (%0, %1, %+1, %-1, %%foo + * + * do_directive checks for directives + * + * expand_smacro is used to expand single line macros + * + * expand_mmacro is used to expand multi-line macros + * + * detoken is used to convert the line back to text + */ #include #include @@ -323,8 +343,9 @@ int any_extrastdmac; /* * Forward declarations. */ +static Token *expand_mmac_params (Token *tline); static Token *expand_smacro (Token *tline); -static void make_tok_num(Token *tok, long val); +static void make_tok_num(Token *tok, long val); /* * Macros for safe checking of token pointers, avoid *(NULL) @@ -1413,7 +1434,7 @@ static int do_directive (Token *tline) if (emitting(istk->conds->state) || istk->conds->state == COND_NEVER) istk->conds->state = COND_NEVER; else { - j = if_condition(tline->next, i); + j = if_condition(expand_mmac_params(tline->next), i); tline->next = NULL; /* it got freed */ free_tlist (origline); if (j < 0) @@ -2279,7 +2300,7 @@ static Token *expand_smacro (Token *tline) white = 0; continue; /* parameter loop */ } - if (ch == br0 && + if (ch == '{' && (brackets>0 || (brackets==0 && !paramsize[nparam]))) { @@ -2289,7 +2310,7 @@ static Token *expand_smacro (Token *tline) continue; /* parameter loop */ } } - if (ch == br2 && brackets>0) + if (ch == '}' && brackets>0) if (--brackets == 0) { brackets = -1; continue; /* parameter loop */ @@ -2966,7 +2987,6 @@ void pp_include_path (char *path) i = nasm_malloc(sizeof(IncPath)); i->path = nasm_strdup(path); i->next = ipath; - ipath = i; } diff --git a/rdoff/Makefile.sc b/rdoff/Makefile.sc index f88e603c..816cc98e 100644 --- a/rdoff/Makefile.sc +++ b/rdoff/Makefile.sc @@ -1,54 +1,112 @@ # Makefile for RDOFF object file utils; part of the Netwide Assembler + # + # The Netwide Assembler is copyright (C) 1996 Simon Tatham and + # Julian Hall. All rights reserved. The software is + # redistributable under the licence given in the file "Licence" + # distributed in the NASM archive. + # + # This Makefile is designed for use under Unix (probably fairly + # portably). + + CC = sc + CCFLAGS = -I..\ -c -a1 -mn -Nc -w2 -w7 -o+time -5 + LINK = link + LINKFLAGS = /noi /exet:NT /su:console + + OBJ=obj + EXE=.exe + + NASMLIB = ..\nasmlib.$(OBJ) + NASMLIB_H = ..\nasmlib.h + LDRDFLIBS = rdoff.$(OBJ) $(NASMLIB) symtab.$(OBJ) collectn.$(OBJ) rdlib.$(OBJ) + RDXLIBS = rdoff.$(OBJ) rdfload.$(OBJ) symtab.$(OBJ) collectn.$(OBJ) + + .c.$(OBJ): + $(CC) $(CCFLAGS) $*.c + + all : rdfdump$(EXE) ldrdf$(EXE) rdx$(EXE) rdflib$(EXE) rdf2bin$(EXE) rdf2com$(EXE) + + rdfdump$(EXE) : rdfdump.$(OBJ) + $(LINK) $(LINKFLAGS) rdfdump.$(OBJ), rdfdump$(EXE); + ldrdf$(EXE) : ldrdf.$(OBJ) $(LDRDFLIBS) + $(LINK) $(LINKFLAGS) ldrdf.$(OBJ) $(LDRDFLIBS), ldrdf$(EXE); + rdx$(EXE) : rdx.$(OBJ) $(RDXLIBS) + $(LINK) $(LINKFLAGS) rdx.$(OBJ) $(RDXLIBS), rdx$(EXE); + rdflib$(EXE) : rdflib.$(OBJ) + $(LINK) $(LINKFLAGS) rdflib.$(OBJ), rdflib$(EXE); + rdf2bin$(EXE) : rdf2bin.$(OBJ) $(RDXLIBS) $(NASMLIB) + $(LINK) $(LINKFLAGS) rdf2bin.$(OBJ) $(RDXLIBS) $(NASMLIB), rdf2bin$(EXE); + rdf2com$(EXE) : rdf2bin$(EXE) + copy rdf2bin$(EXE) rdf2com$(EXE) + + rdf2bin.$(OBJ) : rdf2bin.c + rdfdump.$(OBJ) : rdfdump.c + rdoff.$(OBJ) : rdoff.c rdoff.h + ldrdf.$(OBJ) : ldrdf.c rdoff.h $(NASMLIB_H) symtab.h collectn.h rdlib.h + symtab.$(OBJ) : symtab.c symtab.h + collectn.$(OBJ) : collectn.c collectn.h + rdx.$(OBJ) : rdx.c rdoff.h rdfload.h symtab.h + rdfload.$(OBJ) : rdfload.c rdfload.h rdoff.h collectn.h symtab.h + rdlib.$(OBJ) : rdlib.c rdlib.h + rdflib.$(OBJ) : rdflib.c + + clean : + del *.$(OBJ) rdfdump$(EXE) ldrdf$(EXE) rdx$(EXE) rdflib$(EXE) rdf2bin$(EXE) + + + + + -- 2.11.4.GIT