字符串的实现机制

通常编译器编译一个引用字符串的指令是使用指针来实现的.

字符”/0”表示字符转的结尾(这是C语言,Delphi是在字符串起始地址前添加了一个表示字符串实际长度的数值标值)

char *a={“AAAA”};

在内存中*a实际存放的数据是 41H 41H 41H 41H 00H

int main() { char *a={"AAAA"}; char *b={"BBBB"}; printf("%s%s/n",a,b); return 0; }

反汇编代码如下:

int main() { 012413A0 push ebp ;保护ebp的值 012413A1 mov ebp,esp ;ebp指向当前堆栈指针 012413A3 sub esp,0D8h ;为局部变量预留D8H的空间 012413A9 push ebx ;保护ebx寄存器的值 012413AA push esi 012413AB push edi 012413AC lea edi,[ebp-0D8h] ;edi指向局部变量缓冲区 012413B2 mov ecx,36h 012413B7 mov eax,0CCCCCCCCh 012413BC rep stos dword ptr es:[edi] ;循环复制数据到局部变量缓冲区,全部写入0CCCCCCCCh指令,即int 3指令的机器码。因为局部变量不会被执行,如果执行了程序就会出错,所以这时在这里发生中断。这个是VC编译的Debug版本特有的操作。 char *a={"AAAA"}; 012413BE mov dword ptr [a],offset string "AAAA" (124574Ch) ;字符串的地址存放在a中 char *b={"BBBB"}; 012413C5 mov dword ptr [b],offset string "BBBB" (1245744h) ;字符串的地址存放在b中 printf("%s%s/n",a,b); 012413CC mov esi,esp ;esi指向当前堆栈指针 012413CE mov eax,dword ptr [b] ;字符串”BBBB”的指针存放到eax中 012413D1 push eax ;按照Cdecl调用约定,函数参数从右往左压入栈 012413D2 mov ecx,dword ptr [a] ;字符串”AAAA”的指针存放到ecx中 012413D5 push ecx ;ecx入栈 012413D6 push offset string "%s%s/n" (124573Ch) ;字符串” "%s%s/n”d的地址入栈 012413DB call dword ptr [__imp__printf (12482BCh)] ;调用printf函数 012413E1 add esp,0Ch ;调用者清理堆栈,之前压入了3个4字节的参数,所以现在要从堆栈弹出3*4=0Ch字节 012413E4 cmp esi,esp ;比较esi是否等于esp 012413E6 call @ILT+310(__RTC_CheckEsp) (124113Bh) ;调用_CheckEsp检测esp是否恢复正常 return 0; 012413EB xor eax,eax ;eax清0 } 012413ED pop edi ;恢复edi 012413EE pop esi 012413EF pop ebx 012413F0 add esp,0D8h ;清理堆栈 012413F6 cmp ebp,esp ;比较ebp是否等于esp 012413F8 call @ILT+310(__RTC_CheckEsp) (124113Bh) 012413FD mov esp,ebp ;恢复esp 012413FF pop ebp ;恢复ebp 01241400 ret ;函数返回

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值