标签:its turn 偶数 count 算术运算 数据 字节 pop aaa
它们在存贮器和寄存器、寄存器和输入输出端口之间传送数据.
MOV 传送字或字节.
MOVSX 先符号扩展,再传送.
MOVZX 先零扩展,再传送.
PUSH 把字压入堆栈.
POP 把字弹出堆栈.
PUSHA 把AX,CX,DX,BX,SP,BP,SI,DI依次压入堆栈.
POPA 把DI,SI,BP,SP,BX,DX,CX,AX依次弹出堆栈.
PUSHAD 把EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI依次压入堆栈.
POPAD 把EDI,ESI,EBP,ESP,EBX,EDX,ECX,EAX依次弹出堆栈.
BSWAP 交换32位寄存器里字节的顺序
XCHG 交换字或字节.(至少有一个操作数为寄存器,段寄存器不可作为操作数)
CMPXCHG 比较并交换操作数.(第二个操作数必须为累加器AL/AX/EAX)
XADD 先交换再累加.(结果在第一个操作数里)
XLAT 字节查表转换.----BX指向一张256字节的表的起点,AL为表的索引值(0-255,即0-FFH);返回AL为查表结果.([BX+AL]->AL)
LEA 装入有效地址.例: LEA DX,string ;把偏移地址存到DX.
LDS 传送目标指针,把指针内容装入DS.例: LDS SI,string ;把段地址:偏移地址存到DS:SI.
LES 传送目标指针,把指针内容装入ES.例: LES DI,string ;把段地址:偏移地址存到ES:DI.
LFS 传送目标指针,把指针内容装入FS.例: LFS DI,string ;把段地址:偏移地址存到FS:DI.
LGS 传送目标指针,把指针内容装入GS.例: LGS DI,string ;把段地址:偏移地址存到GS:DI.
LSS 传送目标指针,把指针内容装入SS.例: LSS DI,string ;把段地址:偏移地址存到SS:DI.
ADD 加法.
ADC 带进位加法.
INC 加 1.
AAA 加法的ASCII码调整.
DAA 加法的十进制调整.
SUB 减法.
SBB 带借位减法.
DEC 减 1.
NEG 求反(以 0 减之).
CMP 比较.(两操作数作减法,仅修改标志位,不回送结果).
AAS 减法的ASCII码调整.
DAS 减法的十进制调整.
MUL 无符号乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
IMUL 整数乘法.结果回送AH和AL(字节运算),或DX和AX(字运算),
AAM 乘法的ASCII码调整.
DIV 无符号除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
IDIV 整数除法.结果回送:商回送AL,余数回送AH, (字节运算);或 商回送AX,余数回送DX, (字运算).
AAD 除法的ASCII码调整.
CBW 字节转换为字. (把AL中字节的符号扩展到AH中去)
CWD 字转换为双字. (把AX中的字的符号扩展到DX中去)
CWDE 字转换为双字. (把AX中的字符号扩展到EAX中去)
CDQ 双字扩展. (把EAX中的字的符号扩展到EDX中去)
AND 与运算.
OR 或运算.
XOR 异或运算.
NOT 取反.
TEST 测试.(两操作数作与运算,仅修改标志位,不回送结果).
SHL 逻辑左移.
SAL 算术左移.(=SHL)
SHR 逻辑右移.
SAR 算术右移.(=SHR)
ROL 循环左移.
ROR 循环右移.
RCL 通过进位的循环左移.
RCR 通过进位的循环右移.
以上八种移位指令,其移位次数可达255次.
移位一次时, 可直接用操作码. 如 SHL AX,1.
移位>1次时, 则由寄存器CL给出移位次数.
如 MOV CL,04 SHL AX,CL
DS:SI 源串段寄存器 :源串变址.
ES:DI 目标串段寄存器:目标串变址.
CX 重复次数计数器.
AL/AX 扫描值.
D标志 0表示重复操作中SI和DI应自动增量; 1表示应自动减量.
Z标志 用来控制扫描或比较操作的结束.
MOVS 串传送.( MOVSB 传送字符. MOVSW 传送字. MOVSD 传送双字. )
CMPS 串比较.( CMPSB 比较字符. CMPSW 比较字. )
SCAS 串扫描.把AL或AX的内容与目标串作比较,比较结果反映在标志位.
LODS 装入串.把源串中的元素(字或字节)逐一装入AL或AX中.( LODSB 传送字符. LODSW 传送字. LODSD 传送双字. )
STOS 保存串.是LODS的逆过程.
REP 当CX/ECX<>0时重复.
REPE/REPZ 当ZF=1或比较结果相等,且CX/ECX<>0时重复.
REPNE/REPNZ 当ZF=0或比较结果不相等,且CX/ECX<>0时重复.
REPC 当CF=1且CX/ECX<>0时重复.
REPNC 当CF=0且CX/ECX<>0时重复.
JA/JNBE 不小于或不等于时转移.
JAE/JNB 大于或等于转移.
JB/JNAE 小于转移.
JBE/JNA 小于或等于转移.
以上四条,测试无符号整数运算的结果(标志C和Z).
JG/JNLE 大于转移.
JGE/JNL 大于或等于转移.
JL/JNGE 小于转移.
JLE/JNG 小于或等于转移.
以上四条,测试带符号整数运算的结果(标志S,O和Z).
JE/JZ 等于转移.
JNE/JNZ 不等于时转移.
JC 有进位时转移.
JNC 无进位时转移.
JNO 不溢出时转移.
JNP/JPO 奇偶性为奇数时转移.
JNS 符号位为 "0" 时转移.
JO 溢出转移.
JP/JPE 奇偶性为偶数时转移.
JS 符号位为 "1" 时转移.
处理器控制指令
HLT 处理器暂停, 直到出现中断或复位信号才继续.
WAIT 当芯片引线TEST为高电平时使CPU进入等待状态.
ESC 转换到外处理器.
LOCK 封锁总线.
NOP 空操作.
STC 置进位标志位.
CLC 清进位标志位.
CMC 进位标志取反.
STD 置方向标志位.
CLD 清方向标志位.
STI 置中断允许位.
CLI 清中断允许位.
DW 定义字(2字节).
PROC 定义过程.
ENDP 过程结束.
SEGMENT 定义段.
ASSUME 建立段寄存器寻址.
ENDS 段结束.
END 程序结束.
CLC 进位位置0指令
CMC 进位位求反指令
STC 进位位置为1指令
CLD 方向标志置1指令
STD 方向标志位置1指令
CLI 中断标志置0指令
STI 中断标志置1指令
NOP 无操作
HLT 停机
WAIT 等待
ESC 换码
LOCK 封锁
栈(stack):存放局部变量,向地址减小的方向增长
add:加法指令,第一个是目标操作数,第二个是源操作数,格式为:目标操作数 = 目标操作数 + 源操作数;
rep 根据ECX寄存器的值进行重复循环操作
#include "pch.h"
#include <iostream>
using namespace std;
int Add(int x, int y)
{
00A117E0 55 push ebp //栈基址寄存器内容送栈顶
00A117E1 8B EC mov ebp,esp //栈顶寄存器内容为当前栈基址 (函数调用压栈后更新栈基址为原先的栈顶,原先的栈基址已经保存在栈顶,故而能够在函数调用返回后找到上一层函数的起始地址)
00A117E3 81 EC CC 00 00 00 sub esp,0CCh //esp-0cch,相当于栈往下长了0CCH(51*4)个单位,/*用于预留空间给函数临时变量*/
00A117E9 53 push ebx //基址寄存器压栈
00A117EA 56 push esi //源变址寄存器压栈
00A117EB 57 push edi //目的变址寄存器压栈
00A117EC 8D BD 34 FF FF FF lea edi,[ebp-0CCh] //ebp-0cch这个值送到edi中,也就是说把目的地址寄存器的值设置成了栈基址往下0cch个字节处
00A117F2 B9 33 00 00 00 mov ecx,33h //计数器设置为33H,用于循环计数(51)
00A117F7 B8 CC CC CC CC mov eax,0CCCCCCCCh //eax设置成0CCCCCCCCH
00A117FC F3 AB rep stos dword ptr es:[edi] //rep是循环,stos是串行存储指令,它实现把eax中的数据放入到edi所指的地址中,同时edi后移4个字节
00A117FE B9 09 C0 A1 00 mov ecx,offset _3B624A16_test.cpp (0A1C009h)
00A11803 E8 19 FA FF FF call @__CheckForDebuggerJustMyCode@4 (0A11221h)
int z = 0;
00A11808 C7 45 F8 00 00 00 00 mov dword ptr [z],0 //ptr指针指向变量z的地址,在这个地址上写入双字大小表示的0
z = x + y;
00A1180F 8B 45 08 mov eax,dword ptr [x] //ptr指针指向变量x的地址,取这个地址双字内容送入eax,相当于就是把变量x的内容送eax
00A11812 03 45 0C add eax,dword ptr [y] //ptr指针指向变量y的地址,取这个地址的双字内容与eax内容相加,结果还在eax中
00A11815 89 45 F8 mov dword ptr [z],eax //把eax内容送入z中
return z;
00A11818 8B 45 F8 mov eax,dword ptr [z] //z内容送入eax作为返回值
}
00A1181B 5F pop edi //edi出栈
00A1181C 5E pop esi //esi出栈
00A1181D 5B pop ebx //ebx出栈
00A1181E 81 C4 CC 00 00 00 add esp,0CCh //栈顶指针减去0CCH,相当于退栈清除填充内容
00A11824 3B EC cmp ebp,esp //检查ebp是否小于esp,调用__RTC_CheckEsp检查
00A11826 E8 00 FA FF FF call __RTC_CheckEsp (0A1122Bh)
00A1182B 8B E5 mov esp,ebp //该函数返回后,其基地址变成当前栈中函数的栈顶地址
00A1182D 5D pop ebp //该函数的基地址已经没用了,弹出该函数的基地址
00A1182E C3 ret //返回指令
--- 无源文件 -----------------------------------------------------------------------
00A1182F CC int 3 //断点
00A11830 CC int 3
00A11831 CC int 3
00A11832 CC int 3
00A11833 CC int 3
00A11834 CC int 3
00A11835 CC int 3
00A11836 CC int 3
00A11837 CC int 3
00A11838 CC int 3
00A11839 CC int 3
00A1183A CC int 3
00A1183B CC int 3
00A1183C CC int 3
00A1183D CC int 3
00A1183E CC int 3
00A1183F CC int 3
00A11840 CC int 3
00A11841 CC int 3
00A11842 CC int 3
00A11843 CC int 3
00A11844 CC int 3
00A11845 CC int 3
00A11846 CC int 3
00A11847 CC int 3
00A11848 CC int 3
00A11849 CC int 3
00A1184A CC int 3
00A1184B CC int 3
00A1184C CC int 3
00A1184D CC int 3
00A1184E CC int 3
00A1184F CC int 3
int main()
{
00A118F0 55 push ebp //栈基址寄存器内容压栈
00A118F1 8B EC mov ebp,esp //esp称为新的栈基址
00A118F3 81 EC E4 00 00 00 sub esp,0E4h //栈下移0E4H个字节的空间
00A118F9 53 push ebx //ebx esi edi入栈
00A118FA 56 push esi
00A118FB 57 push edi
00A118FC 8D BD 1C FF FF FF lea edi,[ebp-0E4h] //edi设定
00A11902 B9 39 00 00 00 mov ecx,39h //循环计数器设定
00A11907 B8 CC CC CC CC mov eax,0CCCCCCCCh //eax赋值
00A1190C F3 AB rep stos dword ptr es:[edi] //填充0CCCCCCCCH
00A1190E B9 09 C0 A1 00 mov ecx,offset _3B624A16_test.cpp (0A1C009h)
00A11913 E8 09 F9 FF FF call @__CheckForDebuggerJustMyCode@4 (0A11221h)
int a = 3;
00A11918 C7 45 F8 03 00 00 00 mov dword ptr [a],3 //a = 3
int b = 5;
00A1191F C7 45 EC 05 00 00 00 mov dword ptr [b],5 // b= 5
int ret = 0;
00A11926 C7 45 E0 00 00 00 00 mov dword ptr [ret],0 // ret = 0
ret = Add(a, b);
00A1192D 8B 45 EC mov eax,dword ptr [b] //eax累加寄存器赋值b中内容eax = b = 5
00A11930 50 push eax //eax入栈
00A11931 8B 4D F8 mov ecx,dword ptr [a] //a中内容送ecx ,ecx = a = 3
00A11934 51 push ecx //ecx入栈
00A11935 E8 60 F8 FF FF call Add (0A1119Ah)//调用Add函数
00A1193A 83 C4 08 add esp,8 //esp栈顶寄存器+8,因为一个参数+4,这里有两个参数传入,并且函数参数是向栈上方涨的
00A1193D 89 45 E0 mov dword ptr [ret],eax //eax送入ret变量所处内存地址。注意,此处eax是存储了Add函数的返回值,故而ret = 8
cout << ret << endl;
00A11940 8B F4 mov esi,esp //栈顶寄存器内容送esi
00A11942 68 4E 12 A1 00 push offset std::endl<char,std::char_traits<char> > (0A1124Eh) // "push variable" means push the value of the variable and "push offset variable" means push the offset of the variable.
00A11947 8B FC mov edi,esp //栈顶指针送edi
00A11949 8B 45 E0 mov eax,dword ptr [ret] //ret内容送eax
00A1194C 50 push eax //eax入栈
00A1194D 8B 0D A8 B0 A1 00 mov ecx,dword ptr [_imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A (0A1B0A8h)] //ecx赋值,打印长度确定,循环打印字符,接下来调用打印函数打印字符
00A11953 FF 15 9C B0 A1 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0A1B09Ch)] //调用打印函数,不断打印栈顶的值,栈顶是eax,其值等于ret
00A11959 3B FC cmp edi,esp //检查edi<esp 每个过程函数调用结束后都要比较
00A1195B E8 CB F8 FF FF call __RTC_CheckEsp (0A1122Bh)
00A11960 8B C8 mov ecx,eax //eax送ecx
00A11962 FF 15 A0 B0 A1 00 call dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0A1B0A0h)] //调用打印函数 打印endl
00A11968 3B F4 cmp esi,esp //检查esi<esp
00A1196A E8 BC F8 FF FF call __RTC_CheckEsp (0A1122Bh)
return 0;
00A1196F 33 C0 xor eax,eax //eax清零
}
//退栈函数返回
00A11971 5F pop edi
00A11972 5E pop esi
00A11973 5B pop ebx
00A11974 81 C4 E4 00 00 00 add esp,0E4h
00A1197A 3B EC cmp ebp,esp
00A1197C E8 AA F8 FF FF call __RTC_CheckEsp (0A1122Bh)
00A11981 8B E5 mov esp,ebp
00A11983 5D pop ebp
00A11984 C3 ret
标签:its turn 偶数 count 算术运算 数据 字节 pop aaa
原文地址:https://www.cnblogs.com/czsharecode/p/12303096.html