8088 汇编速查手册
<P>一、数据传输指令 <BR>─────────────────────────────────────── <BR> 它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据. <BR> 1. 通用数据传送指令. <BR> MOV 传送字或字节. <BR> MOVSX 先符号扩展,再传送. <BR> MOVZX 先零扩展,再传送. <BR> PUSH 把字压入堆栈. <BR> POP 把字弹出堆栈. <BR> PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈. <BR> POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈. <BR> PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈. <BR> POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈. <BR> BSWAP 交换32位寄存器里字节的顺序 <BR> XCHG 交换字或字节.( 至少有一个操作数为寄存器,段寄存器不可作为操作数) <BR> CMPXCHG 比较并交换操作数.( 第二个操作数必须为累加器AL/AX/EAX ) <BR> XADD 先交换再累加.( 结果在第一个操作数里 ) <BR> XLAT 字节查表转换. <BR> ── BX 指向一张 256 字节的表的起点, AL 为表的索引值 (0-255,即 <BR> 0-FFH); 返回 AL 为查表结果. ( [BX+AL]->AL ) <BR> 2. 输入输出端口传送指令. <BR> IN I/O端口输入. ( 语法: IN 累加器, {端口号│DX} ) <BR> OUT I/O端口输出. ( 语法: OUT {端口号│DX},累加器 ) <BR> 输入输出端口由立即方式指定时, 其范围是 0-255; 由寄存器 DX 指定时, <BR> 其范围是 0-65535. <BR> 3. 目的地址传送指令. <BR> LEA 装入有效地址. <BR> 例: LEA DX,string ;把偏移地址存到DX. <BR> LDS 传送目标指针,把指针内容装入DS. <BR> 例: LDS SI,string ;把段地址:偏移地址存到DS:SI. <BR> LES 传送目标指针,把指针内容装入ES. <BR> 例: LES DI,string ;把段地址:偏移地址存到ES:DI. <BR> LFS 传送目标指针,把指针内容装入FS. <BR> 例: LFS DI,string ;把段地址:偏移地址存到FS:DI. <BR> LGS 传送目标指针,把指针内容装入GS. <BR> 例: LGS DI,string ;把段地址:偏移地址存到GS:DI. <BR> LSS 传送目标指针,把指针内容装入SS. <BR> 例: LSS DI,string ;把段地址:偏移地址存到SS:DI. <BR> 4. 标志传送指令. <BR> LAHF 标志寄存器传送,把标志装入AH. <BR> SAHF 标志寄存器传送,把AH内容装入标志寄存器. <BR> PUSHF 标志入栈. <BR> POPF 标志出栈. <BR> PUSHD 32位标志入栈. <BR> POPD 32位标志出栈. </P><P>二、算术运算指令 <BR>─────────────────────────────────────── <BR> ADD 加法. <BR> ADC 带进位加法. <BR> INC 加 1. <BR> AAA 加法的ASCII码调整. <BR> DAA 加法的十进制调整. <BR> SUB 减法. <BR> SBB 带借位减法. <BR> DEC 减 1. <BR> NEC 求反(以 0 减之). <BR> CMP 比较.(两操作数作减法,仅修改标志位,不回送结果). <BR> AAS 减法的ASCII码调整. <BR> DAS 减法的十进制调整. <BR> MUL 无符号乘法. <BR> IMUL 整数乘法. <BR> 以上两条,结果回送AH和AL(字节运算),或DX和AX(字运算), <BR> AAM 乘法的ASCII码调整. <BR> DIV 无符号除法. <BR> IDIV 整数除法. <BR> 以上两条,结果回送: <BR> 商回送AL,余数回送AH, (字节运算); <BR> 或 商回送AX,余数回送DX, (字运算). <BR> AAD 除法的ASCII码调整. <BR> CBW 字节转换为字. (把AL中字节的符号扩展到AH中去) <BR> CWD 字转换为双字. (把AX中的字的符号扩展到DX中去) <BR> CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去) <BR> CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去) </P>
<P>三、逻辑运算指令 <BR>─────────────────────────────────────── <BR> AND 与运算. <BR> OR 或运算. <BR> XOR 异或运算. <BR> NOT 取反. <BR> TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果). <BR> SHL 逻辑左移. <BR> SAL 算术左移.(=SHL) <BR> SHR 逻辑右移. <BR> SAR 算术右移.(=SHR) <BR> ROL 循环左移. <BR> ROR 循环右移. <BR> RCL 通过进位的循环左移. <BR> RCR 通过进位的循环右移. <BR> 以上八种移位指令,其移位次数可达255次. <BR> 移位一次时, 可直接用操作码. 如 SHL AX,1. <BR> 移位>1次时, 则由寄存器CL给出移位次数. <BR> 如 MOV CL,04 <BR> SHL AX,CL </P>
<P>四、串指令 <BR>─────────────────────────────────────── <BR> DS:SI 源串段寄存器 :源串变址. <BR> ES:DI 目标串段寄存器:目标串变址. <BR> CX 重复次数计数器. <BR> AL/AX 扫描值. <BR> D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量. <BR> Z标志 用来控制扫描或比较操作的结束. <BR> MOVS 串传送. <BR> ( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. ) <BR> CMPS 串比较. <BR> ( CMPSB 比较字符. CMPSW 比较字. ) <BR> SCAS 串扫描. <BR> 把AL或AX的内容与目标串作比较,比较结果反映在标志位. <BR> LODS 装入串. <BR> 把源串中的元素(字或字节)逐一装入AL或AX中. <BR> ( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. ) <BR> STOS 保存串. <BR> 是LODS的逆过程. <BR> REP 当CX/ECX<>0时重复. <BR> REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复. <BR> REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复. <BR> REPC 当CF=1且CX/ECX<>0时重复. <BR> REPNC 当CF=0且CX/ECX<>0时重复. </P>
<P>五、程序转移指令 <BR>─────────────────────────────────────── <BR> 1>无条件转移指令 (长转移) <BR> JMP 无条件转移指令 <BR> CALL 过程调用 <BR> RET/RETF过程返回. <BR> 2>条件转移指令 (短转移,-128到+127的距离内) <BR> ( 当且仅当(SF XOR OF)=1时,OP1<OP2 ) <BR> JA/JNBE 不小于或不等于时转移. <BR> JAE/JNB 大于或等于转移. <BR> JB/JNAE 小于转移. <BR> JBE/JNA 小于或等于转移. <BR> 以上四条,测试无符号整数运算的结果(标志C和Z). <BR> JG/JNLE 大于转移. <BR> JGE/JNL 大于或等于转移. <BR> JL/JNGE 小于转移. <BR> JLE/JNG 小于或等于转移. <BR> 以上四条,测试带符号整数运算的结果(标志S,O和Z). <BR> JE/JZ 等于转移. <BR> JNE/JNZ 不等于时转移. <BR> JC 有进位时转移. <BR> JNC 无进位时转移. <BR> JNO 不溢出时转移. <BR> JNP/JPO 奇偶性为奇数时转移. <BR> JNS 符号位为 "0" 时转移. <BR> JO 溢出转移. <BR> JP/JPE 奇偶性为偶数时转移. <BR> JS 符号位为 "1" 时转移. <BR> 3>循环控制指令(短转移) <BR> LOOP CX不为零时循环. <BR> LOOPE/LOOPZ CX不为零且标志Z=1时循环. <BR> LOOPNE/LOOPNZ CX不为零且标志Z=0时循环. <BR> JCXZ CX为零时转移. <BR> JECXZ ECX为零时转移. <BR> 4>中断指令 <BR> INT 中断指令 <BR> INTO 溢出中断 <BR> IRET 中断返回 <BR> 5>处理器控制指令 <BR> HLT 处理器暂停, 直到出现中断或复位信号才继续. <BR> WAIT 当芯片引线TEST为高电平时使CPU进入等待状态. <BR> ESC 转换到外处理器. <BR> LOCK 封锁总线. <BR> NOP 空操作. <BR> STC 置进位标志位. <BR> CLC 清进位标志位. <BR> CMC 进位标志取反. <BR> STD 置方向标志位. <BR> CLD 清方向标志位. <BR> STI 置中断允许位. <BR> CLI 清中断允许位. </P>
<P>六、伪指令 <BR>─────────────────────────────────────── <BR> DW 定义字(2字节). <BR> PROC 定义过程. <BR> ENDP 过程结束. <BR> SEGMENT 定义段. <BR> ASSUME 建立段寄存器寻址. <BR> ENDS 段结束. <BR> END 程序结束. <BR></P>
<P>#include "windows.h"</P>
<P>int main(int argc, char *argv[])<BR>{<BR> char buf[MAX_PATH];<BR> HMODULE module;<BR> <BR> module = GetModuleHandle(0);<BR> GetModuleFileName(module, buf, MAX_PATH);<BR> CloseHandle((HANDLE)4);<BR> <BR> __asm <BR> {<BR> lea eax, buf<BR> push 0<BR> push 0<BR> push eax<BR> push ExitProcess<BR> push module<BR> push DeleteFile<BR> push UnmapViewOfFile<BR> ret<BR> }<BR> <BR> return 0;<BR>} <BR>[/code]<BR>后面的那个套汇编,不停地压栈干嘛?</P> 压栈就是在调用一个子程序的时候 因为要用到寄存器 所以要把先前的数据保留下来 <BR> 最后调用完后在出栈 谢谢版主,学习 [em01]我看到有些有编写用lea 或mov 这两个指令的什么区别 lea 是传送的地址 mov 是值 8088的指令跟8086的有什么区别? <P>好贴,虽然不懂,但还是收藏了,相信以后会有用的。</P> LEA(load affective address)<BR>例如取TABLE的偏移地址:<BR> lea bx,table<BR>等价于:mov bx,offset table 8088只能进行8位数据传输。 支持楼主的作品<BR>顶一个!!! <P>非常感谢,顶</P> <P>花了两个早晨在看,都是记的内容,很实用,谢谢总结<BR></P>
回复:(xieriguo)[em01]我看到有些有编写用lea 或...
他们都可以传送偏移地址 不过用MOV 时要用到OFFSET 传送元操作数的偏移地址 但是他只能传送简单的<BR>而用LEA时则可以传送复杂的比如内存寻址方式是的偏移地址 挺全<BR> <P>我看到比这全<BR>补充:<BR>七、寄存器</P><P>1. Register usage in 32 bit Windows<BR>Function parameters are passed on the stack according to the calling conventions </P>
<P>listed on<BR>page 13. Parameters of 32 bits size or less use one DWORD of stack space. </P>
<P>Parameters<BR>bigger than 32 bits are stored in little-endian form, i.e. with the least </P>
<P>significant DWORD at the<BR>lowest address, and DWORD aligned.<BR>Function return values are passed in registers in most cases. 8-bit integers are </P>
<P>returned in<BR>AL, 16-bit integers in AX, 32-bit integers, pointers, and Booleans in EAX, 64-</P>
<P>bit integers in<BR>EDX:EAX, and floating-point values in ST(0). Structures and class objects not </P>
<P>exceeding<BR>64 bits size are returned in the same way as integers, even if the structure </P>
<P>contains floating<BR>point values. Structures and class objects bigger than 64 bits are returned </P>
<P>through a pointer<BR>passed to the function as the first parameter and returned in EAX. Compilers </P>
<P>that don\'t<BR>support 64-bit integers may return structures bigger than 32 bits through a </P>
<P>pointer. The<BR>Borland compiler also returns structures through a pointer if the size is not a </P>
<P>power of 2.<BR>Registers EAX, ECX and EDX may be changed by a procedure. All other general-</P>
<P>purpose<BR>registers (EBX, ESI, EDI, EBP) must be saved and restored if they are used. The </P>
<P>value of<BR>ESP must be divisible by 4 at all times, so don\'t push 16-bit data on the </P>
<P>stack. Segment<BR>registers cannot be changed, not even temporarily. CS, DS, ES, and SS all point </P>
<P>to the flat<BR>segment group. FS is used for a thread environment block. GS is unused, but </P>
<P>reserved.<BR>Flags may be changed by a procedure with the following restrictions: The </P>
<P>direction flag is 0<BR>by default. The direction flag may be set temporarily, but must be cleared </P>
<P>before any call or<BR>return. The interrupt flag cannot be cleared. The floating-point register stack </P>
<P>is empty at the<BR>entry of a procedure and must be empty at return, except for ST(0) if it is used </P>
<P>for return<BR>value. MMX registers may be changed by the procedure and if so cleared by EMMS </P>
<P>before<BR>returning and before calling any other procedure that may use floating-point </P>
<P>registers. All<BR>XMM registers can be modified by procedures. Rules for passing parameters and </P>
<P>return<BR>values in XMM registers are described in Intel\'s application note AP 589 </P>
<P>"Software<BR>Conventions for Streaming SIMD Extensions". A procedure can rely on EBX, ESI, </P>
<P>EDI, EBP<BR>and all segment registers being unchanged across a call to another procedure.<BR>2. Register usage in Linux<BR>The rules for register usage in Linux appear to be almost the same as for 32-bit </P>
<P>windows.<BR>Registers EAX, ECX, and EDX may be changed by a procedure. All other general-</P>
<P>purpose<BR>registers must be saved. There appears to be no rule for the direction flag. </P>
<P>Function return<BR>values are transferred in the same way as under Windows. Calling conventions are </P>
<P>the<BR>same, except for the fact that no underscore is prefixed to public names. I have </P>
<P>no<BR>information about the use of FS and GS in Linux. It is not difficult to make an </P>
<P>assembly<BR>function that works under both Windows and Linux, if only you take these minor </P>
<P>differences<BR>into account.</P>
<P>八、位操作指令,处理器控制指令<BR> 1.位操作指令,8086新增的一组指令,包括位测试,位扫描。BT,BTC,BTR,BTS,BSF,BSR<BR> 1.1 BT(Bit Test),位测试指令,指令格式:<BR> BT OPRD1,OPRD2,规则:操作作OPRD1可以是16位或32位的通用寄存器或者存储单元。操</P>
<P>作数OPRD2必须是8位立即数或者是与OPRD1操作数长度相等的通用寄存器。如果用OPRD2除以</P>
<P>OPRD1,假设商存放在Divd中,余数存放在Mod中,那么对OPRD1操作数要进行测试的位号就</P>
<P>是Mod,它的主要功能就是把要测试位的值送往CF,看几个简单的例子:<BR> 1.2 BTC(Bit Test And Complement),测试并取反用法和规则与BT是一样,但在功能有些</P>
<P>不同,它不但将要测试位的值送往CF,并且还将该位取反。<BR> 1.3 BTR(Bit Test And Reset),测试并复位,用法和规则与BT是一样,但在功能有些不同</P>
<P>,它不但将要测试位的值送往CF,并且还将该位复位(即清0)。<BR> 1.4 BTS(Bit Test And Set),测试并置位,用法和规则与BT是一样,但在功能有些不同,</P>
<P>它不但将要测试位的值送往CF,并且还将该位置位(即置1)。<BR> 1.5 BSF(Bit Scan Forward),顺向位扫描,指令格式:BSF OPRD1,OPRD2,功能:将从右向</P>
<P>左(从最低位到最高位)对OPRD2操作数进行扫描,并将第一个为1的位号送给操作数OPRD1。</P>
<P>操作数OPRD1,OPRD2可以是16位或32位通用寄存器或者存储单元,但OPRD1和OPRD2操作数的</P>
<P>长度必须相等。<BR> 1.6 BSR(Bit Scan Reverse),逆向位扫描,指令格式:BSR OPRD1,OPRD2,功能:将从左向</P>
<P>右(从最高位到最低位)对OPRD2操作数进行扫描,并将第一个为1的位号送给操作数OPRD1。</P>
<P>操作数OPRD1,OPRD2可以是16位或32位通用寄存器或存储单元,但OPRD1和OPRD2操作数的长</P>
<P>度必须相等。<BR> 1.7 举个简单的例子来说明这6条指令:</P>
<P> AA DW 1234H,5678H<BR> BB DW 9999H,7777H<BR> MOV EAX,12345678H<BR> MOV BX,9999H<BR> BT EAX,8;CF=0,EAX保持不变<BR> BTC EAX,8;CF=0,EAX=12345778H<BR> BTR EAX,8;CF=0,EAX=12345678H<BR> BTS EAX,8;CF=0,EAX=12345778H <BR> BSF AX,BX;AX=0<BR> BSR AX,BX;AX=15<BR> <BR> BT WORD PTR [AA],4;CF=1,[AA]的内容不变<BR> BTC WORD PTR [AA],4;CF=1,[AA]=1223H<BR> BTR WORD PTR [AA],4;CF=1,[AA]=1223H<BR> BTS WORD PTR [AA],4;CF=1,[AA]=1234H<BR> BSF WORD PTR [AA],BX;[AA]=0;<BR> BSR WORD PTR [AA],BX;[AA]=15(十进制) <BR> <BR> BT DWORD PTR [BB],12;CF=1,[BB]的内容保持不变<BR> BTC DWORD PTR [BB],12;CF=1,[BB]=76779999H<BR> BTR DWORD PTR [BB],12;CF=1,[BB]=76779999H<BR> BTS DWORD PTR [BB],12;CF=1,[BB]=77779999H<BR> BSF DWORD PTR [BB],12;[BB]=0<BR> BSR DWORD PTR [BB],12;[BB]=31(十进制) </P>
<P> 2.处理器控制指令<BR> 处理器控制指令主要是用来设置/清除标志,空操作以及与外部事件同步等。<BR> 2.1 CLC,将CF标志位清0。<BR> 2.2 STC,将CF标志位置1。<BR> 2.3 CLI,关中断。<BR> 2.4 STI,开中断。<BR> 2.5 CLD,清DF=0。<BR> 2.6 STD,置DF=1。<BR> 2.7 NOP,空操作,填补程序中的空白区,空操作本身不执行任何操作,主要是为了保持程</P>
<P>序的连续性。<BR> 2.8 WAIT,等待BUSY引脚为高。<BR> 2.9 LOCK,封锁前缀可以锁定其后指令的操作数的存储单元,该指令在指令执行期间一直</P>
<P>有效。在多任务环境中,可以用它来保证独占其享内存,只有以下指令才可以用LOCK前缀:<BR> XCHG,ADD,ADC,INC,SUB,SBB,DEC,NEG,OR,AND,XOR,NOT,BT,BTS,BTR,BTC<BR> 3.0 说明处理器类型的伪指令<BR> .8086,只支持对8086指令的汇编<BR> .186,只支持对80186指令的汇编<BR> .286,支持对非特权的80286指令的汇编<BR> .286C,支持对非特权的80286指令的汇编<BR> .286P,支持对80286所有指令的汇编<BR> .386,支持对80386非特权指令的汇编<BR> .386C,支持对80386非特权指令的汇编<BR> .386P,支持对80386所有指令的汇编<BR> 只有用伪指令说明了处理器类型,汇编程序才知道如何更好去编译,连接程序,更好地去检错。</P>
谢谢楼主了~~~
页:
[1]
