类型转换

并不是所有的数据类型之间都可以相互转换,比如结构体与基本类型
带 * 的类型可以强制转,比如:

1
2
3
4
5
6
void Test() {
char* x;
int* y;
x = (char*)10;
y = (int*)x;
}

&符号的使用

& 是地址符,类型是其后面的类型加一个 “*”,任何变量都可以使用 & 来获取地址,但不能用在常量上

1
2
char a = 10;
char* pa = &a; //汇编中就是lea...

带 * 类型变量前加 *

  • 带 * 类型的变量,可以通过在其变量前加 * 来获取其指向内存中存储的值
  • 在带 * 类型的变量前面加 *,类型是其原来的类型减去一个 *

使用 * 来获取 px 指向内存中存储的值:

观察反汇编:

1
2
3
4
5
6
7
8
9
10
11
int x, y;
int* px;
int** px2;
int*** px3;

x = 10;
px = &x;
px2 = &px;
px3 = &px2;

y = *(*(*px3));

用指针操作数组

  • &arr[0] 代表取数组中第一个元素的地址,可以省略为数组名

    1
    2
    3
    4
    char arr[10];

    char* p = &arr[0]; //取数组第一个元素的地址
    char* p2 = arr; //简写
  • *(p+i) = p[i]
    为神马 *(p+i) 就是 p[i]?因为通过 char* p = &arr[0] 知道 p 中存储的是数组的首地址,那么首地址加上 i 再在外面括个 * 就是去访问首地址 + i 的地方

课后作业

  1. 列出每一行的反汇编代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    char a = 10;
    mov byte ptr [ebp-4], 0xA
    short b = 20;
    mov word ptr [ebp-8], 0x14
    int c = 30;
    mov dword ptr [ebp-0Ch], 0x1E

    char* pa = &a;
    lea eax, [ebp-4]
    mov dword ptr [ebp-10h], eax
    short* pb = &b;
    lea ecx, [ebp-8]
    mov dword ptr [ebp-14h], ecx
    int* pc = &c;
    lea edx, [ebp-0Ch]
    mov dword ptr [ebp-18h], edx

    char** ppa = &pa;
    lea eax, [ebp-10h]
    mov dword ptr [ebp-1Ch], eax
    short** ppb = &pb;
    lea ecx, [ebp-14h]
    mov dword ptr [ebp-20h], ecx
    int** ppc = &pc;
    lea edx, [ebp-18h]
    mov dword ptr [ebp-24h], edx
  2. 列出每一行的反汇编

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    int p = 10;
    mov dword ptr [ebp-4], 0xA

    //定义时虽然没有对应的汇编代码,但是已经分配好了位置
    int******* p7; //ebp-8
    int****** p6; //ebp-0ch
    int***** p5; //ebp-10h
    int**** p4; //ebp-14h
    int*** p3; //ebp-18h
    int** p2; //ebp-1ch
    int* p1; //ebp-20h

    p1 = &p;
    lea eax, [ebp-4]
    mov dword ptr [ebp-20h], eax
    p2 = &p1;
    lea ecx, [ebp-20h]
    mov dword ptr [ebp-1ch], ecx
    p3 = &p2;
    lea edx, [ebp-1ch]
    mov dword ptr [ebp-18h], edx
    p4 = &p3;
    lea eax, [ebp-18h]
    mov dword ptr [ebp-14h], eax
    p5 = &p4;
    lea ecx, [ebp-14h]
    mov dword ptr [ebp-10h], ecx
    p6 = &p5;
    lea edx, [ebp-10h]
    mov dword ptr [ebp-0ch], edx
    p7 = &p6;
    lea eax, [ebp-0ch]
    mov dword ptr [ebp-8], eax
  3. 删掉了

  4. 完成代码,实现数组值的互换
    要注意输出时用的是 p

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    void Function() {
    int arr[5] = {1, 2, 3, 4, 5};

    //此处添加代码,使用指针,将数组值倒置
    int* p = arr;
    for (int i = 0; i < 2; i++) {
    int tmp = *(p+i);
    *(p+i) = *(p+4-i);
    *(p+4-i) = tmp;
    }

    //打印数组值的代码已经写完,不需要修改
    for (int k = 0; k < 5; k++) {
    printf("%d\n", *(p+k));
    }
    }