汇编基础

    科技2025-10-23  7

    0000.0001.0010.0011.0100.0101.0110.0111.1000.1001.1010.1011.1100.1101.1110.1111 0       1       2       3       4      5       6       7       8       9       A       B       C       D      E      F

    8位寄存器:AL    CL    DL    BL    AH    CH    DH    BH 16位寄存器:AX    CX    DX    BX    SP    BP    SI    DI 32位寄存器:EAX    ECX    EDX    EBX    ESP    EBP    ESI    EDI

    CF位 无符号数运算,1表示进位,借位,溢出 不然就为0 OF位 有符号数运算,1表示进位,借位,溢出 不然就为0 PF位 奇偶数校验,最后一个字节的1的个数为奇数就为0,为偶数就为1 AF位 算数操作结果的第3位发生进为或借位,就为1,别的情况就为0 ZF位 结果为0,ZF位就为1,可以和CMP或者TEST或者一些指令一起使用,比如:判断两个值是否相等时就可以用 SF位 结果为正就为0,负就为1 DF位 方向标识位,地址从高到低执行,还是低到高执行,会受DF位影响

    EAX FFFF 0001     整体就是32位,一半就是16,再一半8     还有分高低位,例如这里8位的 00 就是AH高8位,01就是AL低8位     所以要修改00就可以指定AH     mov ah,3

    CMP EAX,ECX     和sub减法一样,就是结果不会存到EAX,但是会改变一些寄存器,比如 ZF位 TEST EAX,ECX     和and一样,就是结果不会存在EAX,但是会改变一些寄存器,比如 ZF位 ----------------- mov 寄存器,值     向寄存器 存一个值 例:mov EAX,1     向EAX寄存器存入1

    mov EDX,EAX     把寄存器的值存入另一个寄存器     注意寄存器宽度要一样的

    WORD    16位 DWORD    32位 所有运算都可以是寄存器和内存地址,只要数据宽度相同 结果都是存到前面那个位置

    -----------------基本的运算----------------- MOV DWORD PTR DS:[18FF94],EAX     语法:MOV 数据宽度 PTR DS:[18FF94],数据宽度相同的寄存器     存入内存地址,EAX寄存器的值写入18FF94内存地址 ADD EAX,ECX     相加,EAX的值加上ECX的值,写入到EAX SUB AL,BYTE PTR DS:[18FFA0]     相减,减多少的值可以是寄存器,也可以是内存地址的值 AND DWORD PTR DS:[18FFA0],EAX     与运算  OR DWORD PTR DS:[18FFA0],EAX     或运算 XOR DWORD PTR DS:[18FFA0],EAX     异或^,结果不一样的位是1,一样的位是0 NOT 寄存器/内存     反转结果

    -----------------移动数据:内存到内存----------------- ESI    指定源地址 EDI    指定目标

    寄存器 EFL 00000246 拆为二进制 0000 0000 0000 0000 0010 0100 0110     右边从0开始算的第十位DF位     是0的话,用完MOVS指令ESI和EDI就会+1或+2或+4,取决于你MOVS几字节     是1的话就 -1 -2 -4

    ESI 0018FF8D EDI 0018FFA1 MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]     把 ESI 内存地址的值复制到了 EDI 内存地址     每运行一次 ESI 内存地址和 EDI 内存地址会自加 这里一次复制一个字节所以每次加1 内存地址变成为: ESI 0018FF8E EDI 0018FFA2

    指令简写: MOVSB    相当于MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]    ,复制一个字节 MOVSW    二个字节 MOVSD    四个字节

    -----------------移动数据:寄存器到内存----------------- STOS BYTE PTR ES:[EDI]     AL寄存器的值存储到EDI指定的内存地址 STOS WORD PTR ES:[EDI]     AX寄存器的值存储到EDI指定的内存地址 STOS DWORD PTR ES:[EDI]     EAX寄存器的值存储到EDI指定的内存地址 EDI的值也会和上面一样发生改变,+1 +2 +4 -1 -2 -4 取决于寄存器 EFL的D位和你存储多少字节

    指令简写: STOSB STOSW STOSD

    -----------------重复执行指令(循环指令)----------------- ECX 寄存器相当于计数器,执行一次减一,存的是16进制的值所以一个F执行15次

    MOV ECX,10     修改计数器的值为十六进制的10,执行16次 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]     循环MOVS指令 指令简写: REP MOVSD REP STOSD

    ----------------- 堆栈 ----------------- 堆栈:系统分配好的 专门给程序用的

    FS 7EFDD000     堆栈地址

    ESP 堆栈指针寄存器     记录堆栈用到哪了,大地址开始用,超出范围 = 堆栈溢出

        ----------------- 堆栈源地址修改-----------------      SUB ESP,8         减少堆栈内存4字节,使他跳过两内存地址         不修改那两内存地址,直接跳过那4字节的内存地址         修改下一位内存地址     ADD ESP,8         堆栈使用到的内存地址+8(加四字节)

    !!!出入几个字节 下一位源地址就减几位或加几位     ----------------- 入栈,写入值到栈里-----------------      PUSH EAX         写入4字节的数据到堆栈(ESP)指定的源地址,然后堆栈(ESP)指定的源地址加4字节(下一位写入位置)         写入EAX到当前栈指针源地址,堆栈源地址到下一位         写入字节不同,堆栈源地址也会随着改变     PUSH DWORD PTR DS:[18FFA4]         内存地址的值写入当前堆栈(ESP)指定的源地址     PUSH 8         写入一个立即数

        ----------------- 出栈,栈的值赋值到别的地方-----------------      POP ECX         当前栈源地址的值,赋值给ECX寄存器,然后+4字节,就是到上一位         等下次写入的时候,就会覆取出值存到ECX寄存器的那个内存地址     POP [18FFA4]         一样可以用内存地址,或寄存器

    ----------------- CPU下次执行的位置 ----------------- EIP 寄存器 cpu下次执行的内存地址内的指令 

        ----------------- JMP修改EIP 堆栈(ESP)不会发生改变 -----------------     JMP 004183F4         修改EIP的值     JMP EAX         EIP寄存器写入EAX寄存器的值     JMP DWORD PTR DS:[0018FFB8]         内存地址的 值 写入EIP     ----------------- 修改EIP 堆栈发生改变 -----------------     修改EIP 并把下一行内存地址写入堆栈中,所以发生改变          CALL 004183F4         把004183F4的值写入EIP,再把下一个内存地址写入堆栈(ESP)指定的源地址中         004183F4的值写到了EIP然后下一个内存地址(004183F5)写到了堆栈当前指定的源地址

        ----------------- 堆栈的值 写到EIP -----------------     RETN         当前堆栈内存地址的值写到EIP 并且地址位置+4(到上一位)         可以用在函数,比如CALL调用了函数,然后函数结尾用ret就能回到CALL下一行了

    ----------------- 堆栈值做为参数 ----------------- MOV EAX,DWORD PTR DS:[ESP+4]     ESP上一位的值写入到EAX

    ----------------- JCC指令(判断指令)-----------------  相当于if,谁跟谁判断,比如用的JE就是判断ZF位为1还是0

    JE SHORT ipmsg.004183F8     JE是看ZF位,比如这条指令执行的时候     ZF位为0的时候就不会修改EIP     ZF位为1的时候就会修改EIP      还有很多 比如JG啊 SF位=0F 且 ZF=0就执行命令,不然就跳过这条指令

    Processed: 0.011, SQL: 8