C代码+汇编 C的for汇编学习分析

我不是女神ヾ 2021-11-05 09:28 554阅读 0赞

C语言的代码

  1. int main()
  2. {
  3. char myString[30];
  4. for(int i = 0;i < 30;i++){
  5. myString[i] = '#';
  6. }
  7. return 0;
  8. }

反汇编代码 (32位寄存器 VC++ 6.0反汇编代码)

  1. 0040B76E mov dword ptr [ebp-24h],0 //将 0 赋值给 ( ebp寄存器的内存地址-24H ) 内存地址 所指向的 值
  2. 0040B775 jmp main+30h (0040b780) //直接跳转到 0040b780的地址处
  3. 0040B777 mov eax,dword ptr [ebp-24h] //将 (ebp寄存器内存地址-24H)的内存地址 赋值给 eax的寄存器
  4. 0040B77A add eax,1 // eax = eax + 1
  5. 0040B77D mov dword ptr [ebp-24h],eax //将eax的内存地址 赋值给 (ebp寄存器-24H)指向的内存地址
  6. 0040B780 cmp dword ptr [ebp-24h],1Eh //1EH = 30(十进制) 判断 ebp寄存器-24H 所指向的内存地址的值 与 1EH(30)作比较
  7. 0040B784 jge main+40h (0040b790) //上面一句 如果大于等于 就跳转到 0040b790的内存地址
  8. 0040B786 mov ecx,dword ptr [ebp-24h] // (ebp寄存器-24H)指向的内存地址 赋值给ecx寄存器
  9. 0040B789 mov byte ptr [ebp+ecx-20h],23h // 23H 在ASCLL码表中 指 # , 含义为 将# 以单字节的形式 赋值给 ([ebp+ecx-20h)的内存地址
  10. 0040B78E jmp main+27h (0040b777) // 直接跳转到 0040b777 指向的内存地址

附图: (还不懂的话 我们接着来往下面)
在这里插入图片描述
让我们一句一句的来(代码按照执行逻辑分析)
1.mov dword ptr [ebp-24h],0
寄存器中 ESP寄存区指栈首 EBP寄存器指栈尾 将0以双字类型的形式添加到ebp-24H的内存地址

问题1:为什么是24H呢?

答:24H = 36(十进制),C代码中 char myString[30]; 数组的大小是30, 因为是32位寄存器,四字节,所以是32, 代码中有for循环需要计数, 多了一个计数器存值的内存(我也是看了汇编内存才知道的…)
在这里插入图片描述
2.jmp main+30h (0040b780)
直接跳转到 0040b780的内存地址,没有什么好说的. 符合for循环的执行逻辑

  1. cmp dword ptr [ebp-24h],1Eh
    //1EH = 30(十进制) 判断 ebp寄存器-24H 所指向的内存地址的值(19FF1C) 与 1EH(30)作比较
    也就是拿 第一句 ebx的值 与 30比较 // C语言代码 i < 30
  2. jge main+40h (0040b790)
    参考上一句 如果ebx>=30则跳转到0040b790的内存地址 也是跳出循环
    5.mov ecx,dword ptr [ebp-24h]
    个人理解: ecx寄存器一般是计数寄存器,将 ebp寄存器-24H 所指向的内存地址的值(19FF1C) 0 赋值给 ecx寄存器,如图
    在这里插入图片描述
    6.mov byte ptr [ebp+ecx-20h],23h
    23H 在ASCLL码表中 指 # , 含义为 将# 以单字节的形式 赋值给 ([ebp+ecx-20h)的内存地址,如图
    在这里插入图片描述
  3. jmp main+27h (0040b777)
    直接跳转到 0040b777 指向的内存地址 循环判断 执行
    8.mov eax,dword ptr [ebp-24h]
    9.add eax,1 // eax = eax + 1

    将 (ebp寄存器内存地址-24H)的内存地址 赋值给 eax的寄存器,然后值在 +1 也就是计数器在+1.默认值是0

在这里插入图片描述

  1. mov dword ptr [ebp-24h],eax
    将eax的值 赋值到了 [ebp-24h]指向的内存地址的值(19FF1C)
    在这里插入图片描述

这时执行第三步 进行判断,然后重复执行直到退出循环

总结:
byte ptr [ebp+ecx-20h] //字节类型 00
word ptr [ebp-24h] /字类型 16位寄存器 0000
dword ptr [ebp-24h] //双字类型 32为寄存器 00000000

疑问 字节类型为什么是两个0?

答案 1byte=8bit
1 int = 4byte
字节类型 = 8byte 也就是2int 也就是 00
字类型 = 16byte 也就是4int’ 也就是 0000
双字类型 = 32byte 也就是8int 也就是 00000000
指令的参考:https://blog.csdn.net/qq_35349982/article/details/98872417

发表评论

表情:
评论列表 (有 0 条评论,554人围观)

还没有评论,来说两句吧...

相关阅读