# 汇编基础 [TOC] ## 通用寄存器  ## 位运算 ### 与运算  ### 或运算  ### 异或运算  ### 非运算  ## 内存  32位每个进程都有地址,地址寻址宽度是4g,每个应用都只能有4g  ``` # 往内存中写入数据 mov byte ptr ds:[xxx],1 宽度:byte、word、dword:一字节、两字节、四字节 mov byte ptr ss:[esp+4],1 # 如果包含寄存器 []:内存编号 ``` ### 内存地址的5种形式      ## 储存模式  - 大端模式存储1A2C3E4F  - 小端模式存储1A2C3E4F  > dtdebug查看分别以字节/字/双字查看内存(db dw dd) ## 常用汇编指令 ### mov移动指令  ### add加法指令  ### sub减法指令  ### and与运算指令  ### 或运算指令  ### 异或运算指令  ### 非指令  ### movs指令,从内存—>内存 ```assembly movs byte ptr es:[edi],byte ptr ds:[esi] # 简写 movsb movsw movsd ``` > 复制一个字节的内存,从esi到edi(两个寄存器内容分别为内存编号) > > 执行之后,edi和esi,会相应的加上复制的对应字节位数(edi+byte , esi+byte) > > EFL寄存器中第10位DF(方向为)的值为0,则是加,1则是减  ### stos指令,从寄存器—>内存 ```assembly stos byte ptr es:[edi] # 简写 stosb stosw stosd ```  ### rep重复指令 ```assembly # rep {需要执行的命令} mov ECX,10 # 重复基于ECX的次数 rep movs byte ptr es:[edi],byte ptr ds:[esi] ``` ## 堆栈 > 是一块特殊的内存,操作系统分配好的,程序执行过程中,使用的一块内存。堆栈是大地址往小地址用 - esp栈指针寄存器(当前堆栈用到哪里) - ebp栈底指针(当前堆栈底部位置) ### posh存入堆栈指令 - eax推入堆栈 ```assembly # 分步执行 mov dword ptr ds:[esp-4],eax sub esp,4 # posh推入值 posh eax #eax存入堆栈 ```  ### pop取出指令 - 取出栈值,存入ecx ```assembly # 单步执行 mov ecx,dword ptr ds:[esp] add esp,4 # pop取出执行 pop ecx ```  ## 修改eip寄存器(修改指向cpu下一次执行的命令地址) ### jmp指令 > 修改eip的值 > > MOV EIP,寄存器/立即数/内存 简写为JMP 寄存器/立即数/内存 ```assembly mov eip,1 = jmp 1 ``` ### call指令 1、修改eip 2、吧call的下一行地址压入堆栈中 3、ESP值-4 ```assembly # 执行 call 004183FA # 分步 mov eip,004183FA posh 004183FA -> mov dword ptr ds:[esp-4],004183FA sub esp,4 ```  ### ret指令 ```assembly # 执行 retn # 分步执行 add esp,4 mov eip,[esp-4] # 内平栈 push 1 push 2 call 773501e6 ...... mov eax,1 retn 8 # 分步 push 1 push 2 call 773501e6 add esp,8 ...... mov eax,1 retn ```  ### jcc指令 > 按条件判断是否修改eip指令 #### 标志寄存器 > 运算指令都会影响标志寄存器  ##### CF位 ```assembly mov al,0x0fe add al,2 # 加出现溢出,最高位还在向前进位,c位为1 mov al,0x7f add al,0xff # 减出现溢出,最高位还在向前借位,c位为1 ```  ##### RF位 ```assembly mov ax,0x113 # 0000 0001 0001 0011 add ax,1 # 0000 0001 {0001 0100} 最后一个字节,如果1的个数为偶数,p位为1,否则为0 ```  ##### AF位  ##### ZF位 ```assembly mov eax,100 mov ecx,100 cmp eax,ecx # cmp指令相当于sub,但相减结果不保存到第一个操作数中,只影响标记寄存器 test eax,eax # 指令相对于and指令,但与运算的结果不保存到操作数中,只影响标记寄存器 ```  ##### SF位 ```assembly mov al,0x7f add al,2 # 保存追高有效位,一般用于看正负 ```  ##### OF位 ```assembly mov al,0x7f add al,2 ```  ##### DF位 ```assembly STD # DF设置1 CLD # DF设置0 ```  ## 寄存器 - EFL标志寄存器 - ECX计数器 - EAX返回值 - ESP、EBP堆栈顶、栈低 - ESI、EDI串复制的首地址和目的地址 - EIP指向cpu下一次执行的命令地址 ## 堆栈寻址方法 ### ESP寻址 ```assembly push 1 # 参数 push 2 # call 4183ee .... push ecx # push edx # 保存寄存器原始值 push ebx # mov ecx dword ptr ss:[esp+10] #ESP寻址 add ecx dowrd ptr ss:[esp+14] #ESP寻址 mov eax,ecx # 转入返回值 pop ebx # pop edx # 还原寄存器 pop ecx # retn ``` ### EBP寻址 ```assembly push 1 # 参数 push 2 # call 4183ee ...... # 提升堆栈 push ebp # 保留原ebp的值 mov ebp,esp # 提升栈底 sub esp,10 # 提升栈顶 mov ecx dword ptr ss:[esp+8] #EBP寻址 add ecx dowrd ptr ss:[esp+C] #EBP寻址 mov eax,ecx # 转入返回值 # 恢复堆栈 mov esp,ebp # 恢复esp栈顶 pop ebp # 还原ebp栈底 retn 8 # 内平栈+返回 ``` - ==> ebp - $-10 esp   ## 调试相关 - ini 3 # cpu遇到这个程序就会停下来,转到调试器 CC - EFL的TF位置1,CPU会进入单步执行模式