• 反汇编:指针数组和数组指针


    指针数组:

    第一种写法:

    代码如下:

    #include<stdio.h>
    
    int main(){
    	//指针数组
    	char arr[3][10] = {
    		"aaaaa",
    		"bbbbb",
    		"ccccc"
    	};
    
    	printf("%s",arr[1]);
    }
    

    反汇编如下:

    0040D440 >/> 55            PUSH EBP
    0040D441  |.  8BEC          MOV EBP,ESP
    0040D443  |.  83EC 60       SUB ESP,60
    0040D446  |.  53            PUSH EBX
    0040D447  |.  56            PUSH ESI
    0040D448  |.  57            PUSH EDI
    0040D449  |.  8D7D A0       LEA EDI,DWORD PTR SS:[EBP-60]
    0040D44C  |.  B9 18000000   MOV ECX,18
    0040D451  |.  B8 CCCCCCCC   MOV EAX,CCCCCCCC
    0040D456  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
    0040D458  |.  A1 2C204200   MOV EAX,DWORD PTR DS:[??_C@_05NHMN@aaaaa?$AA@]         ;  将保存字符串的地址四个字节赋值给eax
    0040D45D  |.  8945 E0       MOV DWORD PTR SS:[EBP-20],EAX                          ;  将eax赋值给ebp-20
    0040D460  |.  66:8B0D 30204>MOV CX,WORD PTR DS:[422030]                            ;  除了那四个字节之后存储字符串的地址中的双字节赋值给cx
    0040D467  |.  66:894D E4    MOV WORD PTR SS:[EBP-1C],CX                            ;  也就是把aaaaa最后一个a的值赋值给ebp-1c,以0结尾
    0040D46B  |.  33D2          XOR EDX,EDX                                            ;  清空edx
    0040D46D  |.  8955 E6       MOV DWORD PTR SS:[EBP-1A],EDX
    0040D470  |.  A1 24204200   MOV EAX,DWORD PTR DS:[??_C@_05GKCJ@bbbbb?$AA@]
    0040D475  |.  8945 EA       MOV DWORD PTR SS:[EBP-16],EAX
    0040D478  |.  66:8B0D 28204>MOV CX,WORD PTR DS:[422028]
    0040D47F  |.  66:894D EE    MOV WORD PTR SS:[EBP-12],CX
    0040D483  |.  33D2          XOR EDX,EDX
    0040D485  |.  8955 F0       MOV DWORD PTR SS:[EBP-10],EDX
    0040D488  |.  A1 1C204200   MOV EAX,DWORD PTR DS:[??_C@_05BHF@ccccc?$AA@]
    0040D48D  |.  8945 F4       MOV DWORD PTR SS:[EBP-C],EAX
    0040D490  |.  66:8B0D 20204>MOV CX,WORD PTR DS:[422020]
    0040D497  |.  66:894D F8    MOV WORD PTR SS:[EBP-8],CX
    0040D49B  |.  33D2          XOR EDX,EDX
    0040D49D  |.  8955 FA       MOV DWORD PTR SS:[EBP-6],EDX                           ;  清空ebp-6的高位两字节
    0040D4A0  |.  8D45 EA       LEA EAX,DWORD PTR SS:[EBP-16]                          ;  取bbbbb的字符串赋值给eax
    0040D4A3  |.  50            PUSH EAX                                               ; /<%s>
    0040D4A4  |.  68 0C244200   PUSH OFFSET my.??_C@_02DILL@?$CFs?$AA@                 ; |format = "%s"
    0040D4A9  |.  E8 82020000   CALL my.printf                                         ; printf
    

    第二种写法:

    代码如下:

    #include<stdio.h>
    
    int main(){
    	//指针数组
    
    
    	//还可以这样表示
    
    	//相当于定义为arr[][10]
    	char* arr[10] = {
    		"aaaaa",
    		"bbbbb",
    		"ccccc"
    	};
    	
    	printf("%s",arr[1]);
    
    }
    

    反汇编如下:

    0040D440 >/> 55            PUSH EBP
    0040D441  |.  8BEC          MOV EBP,ESP
    0040D443  |.  83EC 68       SUB ESP,68
    0040D446  |.  53            PUSH EBX
    0040D447  |.  56            PUSH ESI
    0040D448  |.  57            PUSH EDI
    0040D449  |.  8D7D 98       LEA EDI,DWORD PTR SS:[EBP-68]
    0040D44C  |.  B9 1A000000   MOV ECX,1A
    0040D451  |.  B8 CCCCCCCC   MOV EAX,CCCCCCCC
    0040D456  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
    0040D458  |.  C745 D8 2C204>MOV DWORD PTR SS:[EBP-28],OFFSET my.??_C@_05NHMN@aaaaa?$AA@     ;  将保存字符串的地址赋值给ebp-28中
    0040D45F  |.  C745 DC 24204>MOV DWORD PTR SS:[EBP-24],OFFSET my.??_C@_05GKCJ@bbbbb?$AA@     ;  将保存字符串的地址赋值给ebp-24中
    0040D466  |.  C745 E0 1C204>MOV DWORD PTR SS:[EBP-20],OFFSET my.??_C@_05BHF@ccccc?$AA@      ;  将保存字符串的地址赋值给ebp-20中
    0040D46D  |.  B9 07000000   MOV ECX,7                                                       ;  ecx赋值为7
    0040D472  |.  33C0          XOR EAX,EAX                                                     ;  清空eax
    0040D474  |.  8D7D E4       LEA EDI,DWORD PTR SS:[EBP-1C]                                   ;  ebp-1c的地址赋值给edi
    0040D477  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]                                     ;  初始化00000000
    0040D479  |.  8B45 DC       MOV EAX,DWORD PTR SS:[EBP-24]                                   ;  将存储bbbbb的地址赋值给eax
    0040D47C  |.  50            PUSH EAX                                                        ; /<%s>
    0040D47D  |.  68 0C244200   PUSH OFFSET my.??_C@_02DILL@?$CFs?$AA@                          ; |format = "%s"
    0040D482  |.  E8 A9020000   CALL my.printf                                                  ; printf
    0040D487  |.  83C4 08       ADD ESP,8
    0040D48A  |.  5F            POP EDI
    0040D48B  |.  5E            POP ESI
    0040D48C  |.  5B            POP EBX
    0040D48D  |.  83C4 68       ADD ESP,68
    0040D490  |.  3BEC          CMP EBP,ESP
    0040D492  |.  E8 59020000   CALL my.__chkesp
    0040D497  |.  8BE5          MOV ESP,EBP
    0040D499  |.  5D            POP EBP
    0040D49A  .  C3            RETN
    

    总结:

    1、第一种方式:赋值的是字符串的字符数据

    2、第二种方式:赋值的是字符串的地址


    数组指针:

    代码如下:

    #include<stdio.h>
    
    int main(){
    	int arr[] = {1,2,3,4,5,6,7,8,9,0};  //一维数组
    
    	int(*px)[2][2] = (int (*)[2][2])arr; 
    
    	printf("%d
    ",(*px)[1][1]);
    	px++;
    	printf("%d
    ",(*px)[1][1]);
    	return 0;
    
    }
    

    反汇编如下:

    0040D756  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]
    0040D758  |.  C745 D8 01000>MOV DWORD PTR SS:[EBP-28],1              ;  1
    0040D75F  |.  C745 DC 02000>MOV DWORD PTR SS:[EBP-24],2              ;  2
    0040D766  |.  C745 E0 03000>MOV DWORD PTR SS:[EBP-20],3              ;  3
    0040D76D  |.  C745 E4 04000>MOV DWORD PTR SS:[EBP-1C],4              ;  4
    0040D774  |.  C745 E8 05000>MOV DWORD PTR SS:[EBP-18],5              ;  5
    0040D77B  |.  C745 EC 06000>MOV DWORD PTR SS:[EBP-14],6              ;  6
    0040D782  |.  C745 F0 07000>MOV DWORD PTR SS:[EBP-10],7              ;  7
    0040D789  |.  C745 F4 08000>MOV DWORD PTR SS:[EBP-C],8               ;  8
    0040D790  |.  C745 F8 09000>MOV DWORD PTR SS:[EBP-8],9               ;  9
    0040D797  |.  C745 FC 00000>MOV DWORD PTR SS:[EBP-4],0               ;  0
    0040D79E  |.  8D45 D8       LEA EAX,DWORD PTR SS:[EBP-28]            ;  数组的首地址赋值给eax,eax就为0012FF58
    0040D7A1  |.  8945 D4       MOV DWORD PTR SS:[EBP-2C],EAX            ;  将存储数组的首地址赋值给ebp-2c指向的值
    0040D7A4  |.  8B4D D4       MOV ECX,DWORD PTR SS:[EBP-2C]            ;  将 当前数组首地址 赋值给ecx
    0040D7A7  |.  8B51 0C       MOV EDX,DWORD PTR DS:[ECX+C]             ;  ecx+C 相当于当前的地址加上0xC,可以理解为跳过两个int字节取下一组的第一个,也就是(*px)[1][1]
    0040D7AA  |.  52            PUSH EDX                                 ; /<%d>
    0040D7AB  |.  68 1C204200   PUSH OFFSET my.??_C@_03HMFC@?$CFd?6?$AA@ ; |format = "%d
    "
    0040D7B0  |.  E8 FB38FFFF   CALL my.printf                           ; printf
    0040D7B5  |.  83C4 08       ADD ESP,8                                ;  堆栈平衡,下面就是准备输出代码中第二个printf了
    0040D7B8  |.  8B45 D4       MOV EAX,DWORD PTR SS:[EBP-2C]            ;  当前的数组的首地址赋值给eax
    0040D7BB  |.  83C0 10       ADD EAX,10                               ;  现在是eax+10,相当于跳过两段,每段2个数,8字节,那就是跳过16字节
    0040D7BE  |.  8945 D4       MOV DWORD PTR SS:[EBP-2C],EAX            ;  当前的eax地址赋值给ebp-2c指向的值
    0040D7C1  |.  8B4D D4       MOV ECX,DWORD PTR SS:[EBP-2C]            ;  取其中的值给ecx
    0040D7C4  |.  8B51 0C       MOV EDX,DWORD PTR DS:[ECX+C]             ;  ecx+C指向的值赋值给edx
    0040D7C7  |.  52            PUSH EDX                                 ; /<%d>
    0040D7C8  |.  68 1C204200   PUSH OFFSET my.??_C@_03HMFC@?$CFd?6?$AA@ ; |format = "%d
    "
    0040D7CD  |.  E8 DE38FFFF   CALL my.printf                           ; printf
    0040D7D2  |.  83C4 08       ADD ESP,8
    0040D7D5  |.  33C0          XOR EAX,EAX
    0040D7D7  |.  5F            POP EDI
    0040D7D8  |.  5E            POP ESI
    0040D7D9  |.  5B            POP EBX
    0040D7DA  |.  83C4 6C       ADD ESP,6C
    0040D7DD  |.  3BEC          CMP EBP,ESP
    0040D7DF  |.  E8 4C39FFFF   CALL my.__chkesp
    0040D7E4  |.  8BE5          MOV ESP,EBP
    0040D7E6  |.  5D            POP EBP
    0040D7E7  .  C3            RETN
    

  • 相关阅读:
    error C2143: syntax error : missing ';' before 'type'
    【剑指Offer面试编程题】题目1360:乐透之猜数游戏--九度OJ
    【剑指Offer面试编程题】题目1362:左旋转字符串--九度OJ
    【剑指Offer面试编程题】题目1361:翻转单词顺序--九度OJ
    【剑指Offer面试编程题】题目1354:和为S的连续正数序列--九度OJ
    【剑指Offer面试编程题】 题目1350:二叉树的深度--九度OJ
    Oracle个人自学笔记
    【转载】Oracle sqlplus中最简单的一些命令,设置显示的格式
    IntelliJ IDEA常用快捷键大全
    凤凰系统(Phoenix OS)PC版安装,电脑上体验功能丰富的安卓系统
  • 原文地址:https://www.cnblogs.com/zpchcbd/p/12303225.html
Copyright © 2020-2023  润新知