鱼C论坛

 找回密码
 立即注册
查看: 1706|回复: 4

看不懂调试的汇编代码,求详注(关于C指针-从A字符串抄到B字符患)

[复制链接]
发表于 2014-4-17 22:56:31 | 显示全部楼层 |阅读模式
30鱼币
本帖最后由 欣欣celin 于 2014-4-18 22:30 编辑
#include "stdio.h"
void main()
{
    void copyString(char *from, char *to);

    char *a = "i am a teacher";
    char *b = "you are a student";

    printf("string a = %s\nstring b = %s\n", a, b);
    printf("copy string a to b: \n");

    copyString(a, b);

    printf("\nstring a - %s\nstring b - %s\n", a, b);
}
void copyString(char *from, char *to)
{
    for(; *from != '\0'; from++, to++)
    {
        *to = *from;
    }
    *to = '\0';
}
以上代码,调器如下:(汇编看不懂,求详注,感激感激{:7_174:})
2:    #include "stdio.h"
3:    void main()
4:    {
00401020   push        ebp
00401021   mov         ebp,esp
00401023   sub         esp,48h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-48h]
0040102C   mov         ecx,12h
00401031   mov         eax,0CCCCCCCCh
00401036   rep stos    dword ptr [edi]
5:        void copyString(char *from, char *to);
6:
7:        char *a = "i am a teacher";
00401038   mov         dword ptr [ebp-4],offset string "i am a teacher" (00422098)
8:        char *b = "you are a student";
0040103F   mov         dword ptr [ebp-8],offset string "you are a student" (00422080)
9:
10:       printf("string a = %s\nstring b = %s\n", a, b);
00401046   mov         eax,dword ptr [ebp-8]
00401049   push        eax
0040104A   mov         ecx,dword ptr [ebp-4]
0040104D   push        ecx
0040104E   push        offset string "string a = %s\nstring b = %s\n" (0042205c)
00401053   call        printf (00401130)
00401058   add         esp,0Ch
11:       printf("copy string a to b: \n");
0040105B   push        offset string "copy string a to b: \n" (00422040)
00401060   call        printf (00401130)
00401065   add         esp,4
12:
13:       copyString(a, b);
00401068   mov         edx,dword ptr [ebp-8]
0040106B   push        edx
0040106C   mov         eax,dword ptr [ebp-4]
0040106F   push        eax
00401070   call        @ILT+0(_copyString) (00401005)      
//单步运行到这句,弹出对话框说"unhandled exception in copy exe:0xc0000005: access violation",何解会访问冲突呢{:7_154:}
00401075   add         esp,8
14:
15:       printf("\nstring a - %s\nstring b - %s\n", a, b);
00401078   mov         ecx,dword ptr [ebp-8]
0040107B   push        ecx
0040107C   mov         edx,dword ptr [ebp-4]
0040107F   push        edx
00401080   push        offset string "\nstring a - %s\nstring b - %s\n" (0042201c)
00401085   call        printf (00401130)
0040108A   add         esp,0Ch
16:   }
0040108D   pop         edi
0040108E   pop         esi
0040108F   pop         ebx
00401090   add         esp,48h
00401093   cmp         ebp,esp
00401095   call        __chkesp (004011b0)
0040109A   mov         esp,ebp
0040109C   pop         ebp
0040109D   ret


17:   void copyString(char *from, char *to)
18:   {
004010C0   push        ebp
004010C1   mov         ebp,esp
004010C3   sub         esp,40h
004010C6   push        ebx
004010C7   push        esi
004010C8   push        edi
004010C9   lea         edi,[ebp-40h]
004010CC   mov         ecx,10h
004010D1   mov         eax,0CCCCCCCCh
004010D6   rep stos    dword ptr [edi]
19:       for(; *from != '\0'; from++, to++)
004010D8   jmp         copyString+2Ch (004010ec)
004010DA   mov         eax,dword ptr [ebp+8]
004010DD   add         eax,1
004010E0   mov         dword ptr [ebp+8],eax
004010E3   mov         ecx,dword ptr [ebp+0Ch]
004010E6   add         ecx,1
004010E9   mov         dword ptr [ebp+0Ch],ecx
004010EC   mov         edx,dword ptr [ebp+8]
004010EF   movsx       eax,byte ptr [edx]
004010F2   test        eax,eax
004010F4   je          copyString+42h (00401102)
20:       {
21:           *to = *from;
004010F6   mov         ecx,dword ptr [ebp+0Ch]
004010F9   mov         edx,dword ptr [ebp+8]
004010FC   mov         al,byte ptr [edx]
004010FE   mov         byte ptr [ecx],al
22:       }
00401100   jmp         copyString+1Ah (004010da)
23:       *to = '\0';
00401102   mov         ecx,dword ptr [ebp+0Ch]
00401105   mov         byte ptr [ecx],0
24:   }
00401108   pop         edi
00401109   pop         esi
0040110A   pop         ebx
0040110B   mov         esp,ebp
0040110D   pop         ebp
0040110E   ret

最佳答案

查看完整内容

首先。。。我们先解决你会什么会报访问内存错误。。。。 是因为。。*to = *from。。。 而to又是引用的a。。。from引用的b 本来。。。看着貌似没错啊。。 但是。。。你忘了。。你定义的是char *a, char *b。。。也就是说。。。那两个字符串是自数据区中。。。a直接指向。。。数据区的变量。。。b也是直接指向数据区的变量。。 而这个数据区是只读的。。。也就是不可写。。。那么你在进行写操作时当然要报错了。。 解决办法很 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-17 22:56:32 | 显示全部楼层
本帖最后由 向往青莲 于 2014-4-18 08:57 编辑

首先。。。我们先解决你会什么会报访问内存错误。。。。
是因为。。*to = *from。。。
而to又是引用的a。。。from引用的b
本来。。。看着貌似没错啊。。
但是。。。你忘了。。你定义的是char *a, char *b。。。也就是说。。。那两个字符串是自数据区中。。。a直接指向。。。数据区的变量。。。b也是直接指向数据区的变量。。
而这个数据区是只读的。。。也就是不可写。。。那么你在进行写操作时当然要报错了。。
解决办法很简答

char *a
char *b
改为
char a[]
char b[]至于为什么这样定义了。。就没错。。。那是因为。。。这时a不是指针了。。它是数组变量。。。所以虽然字符串一样是在只读数据区内。。但是进行操作时系统会先把数据复制到堆栈再进行操作。。。所以就没可读可写了。。b同理

我直接解释你发上来的汇编了。。。。有些不重要的就不解释了。。。
2:    #include "stdio.h"
3:    void main()
4:    {
00401020   push        ebp                                
00401021   mov         ebp,esp
00401023   sub         esp,48h
00401026   push        ebx
00401027   push        esi
00401028   push        edi
00401029   lea         edi,[ebp-48h]
0040102C   mov         ecx,12h
00401031   mov         eax,0CCCCCCCCh        
00401036   rep stos    dword ptr [edi]                                        ////上面是分配空间,保存变量,填充CC(int 3),乃懂的
5:        void copyString(char *from, char *to);
6:
7:        char *a = "i am a teacher";
00401038   mov         dword ptr [ebp-4],offset string "i am a teacher" (00422098)                //让第一个变量a 指向字符串
8:        char *b = "you are a student";
0040103F   mov         dword ptr [ebp-8],offset string "you are a student" (00422080)        //同上
9:
10:       printf("string a = %s\nstring b = %s\n", a, b);
00401046   mov         eax,dword ptr [ebp-8]
00401049   push        eax
0040104A   mov         ecx,dword ptr [ebp-4]
0040104D   push        ecx
0040104E   push        offset string "string a = %s\nstring b = %s\n" (0042205c)
00401053   call        printf (00401130)                                                                        //上面是压栈printf需要的参数。。。调用printf打印
00401058   add         esp,0Ch                                                        //堆栈平衡
11:       printf("copy string a to b: \n");
0040105B   push        offset string "copy string a to b: \n" (00422040)
00401060   call        printf (00401130)                                //同上
00401065   add         esp,4                                                        //同上
12:
13:       copyString(a, b);
00401068   mov         edx,dword ptr [ebp-8]
0040106B   push        edx
0040106C   mov         eax,dword ptr [ebp-4]
0040106F   push        eax                                                                //压栈参数...也就是先压栈b,再压栈a......._stdcall
00401070   call        @ILT+0(_copyString) (00401005)   //调用copyString函数
//单步运行到这句,弹出对话框说"unhandled exception in copy exe:0xc0000005: access violation",何解会访问冲突呢
00401075   add         esp,8                                                        //堆栈平衡。。。。。。现在我们就当没有冲突哈。。O(∩_∩)O!
14:
15:       printf("\nstring a - %s\nstring b - %s\n", a, b);
00401078   mov         ecx,dword ptr [ebp-8]
0040107B   push        ecx
0040107C   mov         edx,dword ptr [ebp-4]
0040107F   push        edx
00401080   push        offset string "\nstring a - %s\nstring b - %s\n" (0042201c)                //printf同上
00401085   call        printf (00401130)
0040108A   add         esp,0Ch                                //同上
16:   }
0040108D   pop         edi
0040108E   pop         esi
0040108F   pop         ebx
00401090   add         esp,48h
00401093   cmp         ebp,esp
00401095   call        __chkesp (004011b0)        //堆栈平衡检测函数,,系统自动添加的
0040109A   mov         esp,ebp
0040109C   pop         ebp                                        
0040109D   ret                                                                //程序结束

                //解下来分析函数copyString
17:   void copyString(char *from, char *to)
18:   {
004010C0   push        ebp
004010C1   mov         ebp,esp
004010C3   sub         esp,40h
004010C6   push        ebx
004010C7   push        esi
004010C8   push        edi
004010C9   lea         edi,[ebp-40h]
004010CC   mov         ecx,10h
004010D1   mov         eax,0CCCCCCCCh
004010D6   rep stos    dword ptr [edi]                        //同上
19:       for(; *from != '\0'; from++, to++)
004010D8   jmp         copyString+2Ch (004010ec)                        //注意这里就是for循环。。。最好照着调试。。。不然我解释了你也不懂..跳到4010ec
004010DA   mov         eax,dword ptr [ebp+8]                                //这里是下面跳上来的哈
004010DD   add         eax,1                                
004010E0   mov         dword ptr [ebp+8],eax                                //from++
004010E3   mov         ecx,dword ptr [ebp+0Ch]
004010E6   add         ecx,1
004010E9   mov         dword ptr [ebp+0Ch],ecx                        //to++...............注意。。。。这里就是for循环彻底结束。。。下面重复进行操作。。直到测试不成功位置
004010EC   mov         edx,dword ptr [ebp+8]                                //吧b字符串首地址赋值给edx
004010EF   movsx       eax,byte ptr [edx]                                        //取出字符串第一个字符
004010F2   test        eax,eax                                                                //测试是否为'0'
004010F4   je          copyString+42h (00401102)                        //是就调走401102, 不是就继续运行
20:       {
21:           *to = *from;
004010F6   mov         ecx,dword ptr [ebp+0Ch]                                //把第二个字符串首地址给ecx
004010F9   mov         edx,dword ptr [ebp+8]                                //把第一个字符串首地址给edx
004010FC   mov         al,byte ptr [edx]                                        //取出字符串第一个字符
004010FE   mov         byte ptr [ecx],al                                        //把这个字符放到第二个字符串
22:       }
00401100   jmp         copyString+1Ah (004010da)                        //跳到上面。。。也就是说循环结束了第一次。。要进行from++和to++了
23:       *to = '\0';
00401102   mov         ecx,dword ptr [ebp+0Ch]                                //到了这里就表示结束
00401105   mov         byte ptr [ecx],0
24:   }
00401108   pop         edi
00401109   pop         esi
0040110A   pop         ebx
0040110B   mov         esp,ebp
0040110D   pop         ebp
0040110E   ret

就是这样。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-4-18 22:29:17 | 显示全部楼层

感谢您如些详尽的解答,大神就是大神吖{:7_157:}
虽然没完全理解,不过偶会再细细品味,必要时抽时间学一下小甲鱼的汇编看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-4-18 22:55:19 | 显示全部楼层
欣欣celin 发表于 2014-4-18 22:29
感谢您如些详尽的解答,大神就是大神吖
虽然没完全理解,不过偶会再细细品味,必要时抽时间学一下 ...

O(∩_∩)O~
{:7_168:}{:7_168:}{:7_168:}{:7_168:}{:7_168:}{:7_168:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-4-18 23:09:05 | 显示全部楼层

开心每一天很重要,感恩-ing{:7_148:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-26 02:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表