【滴水逆向笔记】第十三章 C语言正向基础

系列文章目录


前言

一、变量的申明

告诉计算机,我要用一块内存

int a,b,c //全局变量的声明
void Fun()
{
    a = 10; //局部变量的声明
    b = 20;
}

总结:
声明就是告诉计算机,我要用一块内存,宽度和存储格式有数据类型决定
计算机给一块内存,取决于变量作用范围,全局变量在编译完就已经分配了内存空间,局部变量所在程序被调用才会分配空间
全局变量不定义值默认是0,但局部变量使用前一定赋初值

二、类型转换

从C语言角度来说,我们需要一个容器存储数据,我们认为一个char足够,我们不断往里面存值,发现不够了,得用另外一个内存来存

#inclde"stdafx.h"

void Fun()
{
    char c = 10;
    int i = c;
}

先看几行汇编

mov al,ff
movsx cx,al
mov al,80
movsx cx,al

这个是先符号扩展,再传送,ecx前面不变,就后面al变

mov al,ff
movzx cx,al
mov al,80
movzx cx,al

先零扩展,再传送,ecx前面都变成0了

扩展

#inclde"stdafx.h"

void Fun()
{
    char i = 0xff;
    short k = i;
    int h = i;
}

反汇编
在这里插入图片描述
如图,是movsx的形式,是有符号的
如果是undesigned,就是无符号

第二个例子

#inclde"stdafx.h"

void Fun()
{
    
    int ni = 0x12345678;
    short si = ni;
    char ci = ni;
}

如图,int是四个字节的,我们想看看能不能存储到更短的short,可以存进去,只是只能存储相对应位的低位,比如si上存5678,ci上就是78

如果两个不同类型的变量,结果是比较类型比较大的那个类型
反汇编代码如下
在这里插入图片描述

#inclde"stdafx.h"

void Fun()
{
    char b = 1;
    unsigned int a = 0xFFFFFFFE;
    printf("%d",a+b)
}

结果是-1,这里提个疑问,为什么是这样?
反汇编:

在这里插入图片描述
正常编程没有人这样写。。。。不管是怎么输入的,计算机都是存储一样的码
这里是printf%d就已经告诉他,这是有符号的了。。。。。

三.语句and程序块

void Fun()
{
    int i;
    int k;
    
    if(x>y)
        i = 100;
        k = 100;
    
}

只执行一句i =100,k不归if语句管

四.参数及返回值的运用

比如写一个函数,进行任意两位数的加法

#inclde"stdafx.h"

void Fun(int x,int y)
{
    int z = x + y;
}

程序执行需要用到外边的值,就需要参数
两个数的和存在Z里面,这个程序一旦执行完,Z是局部变量,这里的值就变成垃圾了

如果想使用这个值怎么办?

#inclde"stdafx.h"

void Fun(int x,int y)
{
    int z = x + y;
    return z;
}
int main(int argc,char* argv[])
{
    int x = Fun(1,2);
    return 0;
}

反汇编
在这里插入图片描述

这里0401041行命令就是return的功劳,如果没有return,就没有这一行04010141,这一行的作用就是已经把局部变量储存到eax了
在main里面执行printf("%d\n",x),发现可以执行

五.关系运算符

== != >= <= > <

#inclde"stdafx.h"

void Fun(int x,int y)
{
    int z = x == y;
    return z;
}

反汇编
在这里插入图片描述
xor ecx,ecx清空ecx里面的值
sete cl:上面cmp,如果两个值一样,cl值为1,不相等就不改,就是0,然后把0或1传入到Z里面

六.逻辑运算符

&&:并且
||:或者
!:非

void Fun(int x,int y)
{
    if(x>1 && y>1 && z>1)
    {
        printf("OK");
        
    }
    else
    {
        printf("error");
    }
}

反汇编
在这里插入图片描述

cmp比较ebp+8(第一个参数)与1谁打,如果小于等于1,就跳转了,跳到C9,然后就执行printf了,观察,都跳到C9那

void Fun(int x,int y)
{
    if(x>1 || y>1 || z||1)
    {
        printf("OK");
        
    }
    else
    {
        printf("error");
    }
}

反汇编
在这里插入图片描述
只要一个成立,就直接打印。到第三个,如果满足大于1,就不跳,如果不满足,就跳到另一个C9执行printf(“error”)

七.单目运算符

void Fun(int x,int y)
{
    int i = 10;
    ++i;
    printf("%d\n",i);
     int x = 10;
    x++;
    printf("%d",x);
}

都打印出11
++i:++在前面是先加,再参与运算
i++:++在后面是先运算,再加

void Fun(int x,int y)
{
    int i = 10;
    int k = i++;
    printf("%d  %d\n",k,i);
 
}

打印出来都是1011
因为i++那一栏,是先把i的值给k,然后i再++
反汇编
在这里插入图片描述
第一个局部变量先给到eax,把eax里的值给第二个局部变量,然后把第一个局部变量给到ecx,然后ecx里的值加1

void Fun(int x,int y)
{
    int i = 10;
    int k = ++i;
    printf("%d  %d\n",k,i);
 
}

打印11 11
反汇编
在这里插入图片描述
先把值给eax,eax加1,再把eax给到局部变量里,然后又取出放到ecx,把这个ecx给第二个局部变量

八.三目运算符

void Fun(int x,int y)
{
    int r = x>y?x:y;
    printf("%D"\n,r);
}
int main()
{
    Fun(1,2);
    return 0;
}

如果x>y是真的,返回x的值,如果是假的,就返回y的值
在这里插入图片描述
和if语句一样,写代码方便

九.循环语句

void Function()
{
    int i =0;
    while(i<=100)
    {
        printf("%d\n",i);
        ++i
    }
   
}
int main(int argc[],char*argv[])
{
    Function();
    return 0;
}

如图为while循环,当i加到101停止循环

void Function()
{
    int i =0;
    for(表达式1;i<=100;++i)
    {
       printf("OK")
    }
   
}

执行顺序:
第一次执行:1 2(判断执行条件,判断for是否停下来)3 4
第二次执行:2(判断是真)4 3
第三次执行 :2(不执行) 从for循环退出

void Function()
{
    int i =0;
    for(int i =0;表达式2;表达式3)
    {
       代码4
    }
   
}

例子:倒序输出数组

void Function2()
{
    int arr[5] = {2,6,1,8,4}
    int n = 4;
    while(n>=0)
    {
        printf("%d\n",arr[n]);
        n--;
    }
}

例子:找出最大值


```c
void Function2()
{
    int arr[5] = {2,6,1,8,4}
    int r = arr[0];
    while(i<=4)
    {
        if(arr[i]>r)
        {
            r = arr[i];
        }
        i++;
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值