编程达人吧 关注:16贴子:35
  • 0回复贴,共1

3.6 表达式

只看楼主收藏回复

本节主要内容:
1. 表达式的格式
2. 表达式的使用
老唐语录:
有些指令只操作两个寄存器,有些指令会操作几十甚至上百个寄存器。
cmp和SUB指令功能是一样的,只是cmp不改变目标操作数的值,同样影响标志位。AND的功能是按位与。TEST与AND的功能相同,只是不改变目标操作数的值,也同样影响标志位。有些指令不能写立即数,有些指令可以全是内存,只要在书写时可编译通过,表示语法正确。
以后我们不需要写汇编,只需要看懂别人写的汇编代码即可。前面提到,定义一个C语言函数格式:int + 函数名 +(+定义的变量+……),可以称C语言是汇编语言的高级书写形式。
表达式的定义:凡是由变量、常量和算术符号链接起来的都可以称为表达式。
在C语言中,XOR表示为“^”,OR表示为“|”,AND表示为“&”。数学里面的表达式有圆括号,中括号和大括号,在C语言中只有圆括号。
比如:
int _abcd(int ab,int cd,int name)
{
int ba;//变量
int dc;
ba = ab+cd;//表达式
return ab;//可以是一个值,也可以写表达式
}
练习:
用各种算术符号写表达式,越复杂越好,编译成功后,观察汇编。
如果看不到逻辑移位,只能看到算术移位,只需将int替换成 unsigned int。
注:int是有符号整型,unsigned int是无符号整型。
在表达式中,任意一个成员又可以表示成表达式,所以可以像嵌套一样无限膨胀。
练习:
int abc(int a,int b,int c)
{
int var;
int h;
int j;
var = 0;
var = (var,0x5,var+0x5);//var = var+0x5;
return 0;
}
“=”左边只能是个变量,不可以是常量或表达式。
逗号和等号也是算术运算符。
单目/双目/三目运算符:b=b+c等价于b+=c。
通过加圆括号和不加圆括号的运算来判断运算符的优先级。
练习:
乘法指令分为有符号乘法和无符号乘法:
计算机做有符号乘法(IMUL)时,首先判断最高位是否为1,为1(负数)时,将1提出来,变成0减去提出1后的数(此时为正数),乘法运算完成后,再用0减去结果。
当做乘法时,目标操作数默认为EAX或EDX:通常乘法会使宽度扩大一倍,8位的乘法需要两个字节保存,32位的乘法需要64位保存。 1个字节相乘时,结果放在AX里面,两个字节相乘时,结果放在EAX里面,4个字节乘法时,结果放在EAX和EDX里面,其中EAX为高位。比如MUL ecx;将ecx乘以eax并将结果放在EAX和EDX中。
除法里面,结果放在EAX里面,余数放在EDX里面。
V = ab%5+ba/7+ba*cd;//“%”:求余,“/”:除法,“*”:乘法
如果目标操作数不设定为EAX,比如IMUL ECX,EAX,则结果会溢出,没有意义。
IMUL后面也可以含有3个操作数,比如IMUL ECX,EAX,0x3;则第三个操作数必须是立即数。
比如:-5*-6 = -1*(0-(-5)) * -1*(0-(-6))。
练习:
写出下列C程序对应的汇编代码
int abc(int a,int b,int c)
{
int v;
int r;
v = a+b+c;
r = a|b&c;
return v+r;
}
int ab(int a,int b,int c,int d)
{
int v;
v = abc(a+b,b+c,c+a)+3;
return v+d+5;
}
调用函数的时候,函数的参数也可以是表达式。
观察函数的规律:
第一条指令都是:push ebp,然后是
push ebp
mov ebp,esp
sub esp,40h
push ebx
push esi
push edi
lea edi,[ebp-40h]//没有定义变量为0x40
mov ecx,10h
mov eax,0CCCCCCCCh
rep stos dword ptr [edi]
如果函数内部定义了变量,则[ebp-4]为第一个变量,[ebp-8]为第二个变量,[ebp+4]为函数返回后执行下一条指令的地址。
函数末尾结构如下:
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
练习:
写一个函数,实现只有表达式由编译器生成汇编,其他部分由自己构造(汇编实现)。
v=a+b+c;r|=a&b|c;
说明:在写裸函数前需要在函数前加__declspec(naked):
__declspec(naked) abc(int a,int b,int c)
{
int v;int r;
__asm
{
push ebp;
mov ebp,esp
sub esp,__LOCAL_SIZE(编译器的宏)//可以写成0x48
}
v=a+b+c;
r|=a&b|c;
__asm
{
mov eax,r
mov esp,ebp
pop ebp
ret
}
}
高级语言的唯一方便之处就是表达式可以按数学思维书写,其他部分都只是固定的格式。
课后理解:
表达式可含有:
1.赋值符号: =
2.运算符号: +、-、*、/
3.不等号符号:==、>=、<=、!=、
课后疑问:
数字3是表达式吗?
回答:是的,属于常量表达式。
课后总结:
凡是由变量、常量和算术符号链接起来的都可以称为表达式。
课后练习:
找出下列对错
int #33;
int a;
int 2a;
int i;
int 3_Alafun()
{
int v;
int a;
int b>a;
v += i++++;
v += ++++i;
return 0;
}


1楼2016-06-13 10:23回复