博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C/C++踩坑记录(二)一段有趣的常量字符串
阅读量:7098 次
发布时间:2019-06-28

本文共 1872 字,大约阅读时间需要 6 分钟。

  hot3.png

测试平台:

Ubuntu 16.04
Windows Mingw GCC gcc version 5.3.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project)

编译器:GCC 5.3

开始不得不吐槽一下网上那些所谓“C语言字符串翻转”的实现的哥们啊,我看到他们代码#include<iostream>和引入STL的时候我都不知道我是该哭还是该笑。
好吧我们开始,从一个简单的问题去分析问题。
先贴代码: 这是我实现的:

#include 
void s_reverse(char *s) { char *h = s; char *t = s; char ch; /* t指向s的尾部 */ while (*t++) {}; t--; /* 与t++抵消 */ t--; /* 回跳过结束符'\0' */ /* 当h和t未重合时,交换它们所指向的字符 */ while (h < t) { ch = *h; *h++ = *t; /* h向尾部移动 */ *t-- = ch; /* t向头部移动 */ }}int main() { char str[] = {'H','e','l','l','o','\0'};//为啥分成两个后面说 char *str_1 = "Hello, World!"; printf("origin str ---> %s\n",str); printf("origin str_1 ---> %s\n",str_1); s_reverse(str); s_reverse(str_1);#ifdef _MSC_VER printf("%s\n", str, "Visual Stadio 2017"); printf("str--->%s\n",str); printf("str_1--->%s\n",str_1);#else printf("str--->%s\n",str); printf("str_1--->%s\n",str_1);#endif return 0;}

这是自带的:

#include 
int main() { char *str ="Hello, World!"; strrev(str); return 0;}

只关注str_1现在分别来看看它们在Mingw下的表现(注:这里Mingw下的效果和Linux测试一致)和MSVC下的表现

MyCode on Mingw
MyCode on MSVC
Official on Mingw
Official on MSVC
那么GCC下的报错问题出在哪呢
追根溯源才是人类的本质,现在生成一下GCC的汇编代码,看看到底发生了什么。

gcc  ./main.c -Sgcc  ./str.c -S

现在分别生成了两份代码 main.s里面我们可以看到这么一段

LC0:	.ascii "Hello, World!\0"

是的这玩意被定义为常量了,无法被访问

使用数组形式声明字符串

char str[] = {'H','e','l','l','o','\0'};

然后我们注释掉str_1相关的东西再来看看str。

Any thin look like good.
现在再来生成汇编代码,我们能看到ascii不见了,所有的东西都在栈上,变成了可以访问的变量。 虽然已经找到问题所在,下面我们来调试一下抛出异常的地方。。
由于str.s的代码只是call _strrev,所以我们根据他的原型,用上面自己实现的代码去寻找问题根源。

gdb main.exe

设置断点

break s_reverse

按下r运行

通过disassemble命令来查看汇编代码
汇编步进调试ni
慢慢的调试过去,会发现

mov    %dl,(%eax)

这句话的意思是从数据寄存器DX低位取数据放到eax中,但是此时数据寄存器是不可写的,所以抛出了异常中断

参考文献:

[DWARF4]

[.cfi指令解读]

[剑指offer]

[汇编中的寄存器]

转载于:https://my.oschina.net/VenusV/blog/3035199

你可能感兴趣的文章
PowerDesigner建表
查看>>
好多问题
查看>>
设计模式 装饰者设计模式
查看>>
Hashmap误区
查看>>
LeetCode 209: Minimum Size Subarray
查看>>
二级域名怎么做优化
查看>>
svn冲突意思
查看>>
Google搜索语法
查看>>
第四次作业-团队编程(二)
查看>>
挑战程序设计竞赛(第2版) 第3章笔记
查看>>
online_judge_1049
查看>>
sentiment analysis(very ish est less)
查看>>
zoj 1280 Intersecting Lines(两直线交点)
查看>>
[C++基础]048_获取数据类型
查看>>
leetcode-Second Highest Salary
查看>>
【JavaScript】——原生Ajax
查看>>
java_包含抽象方法的枚举类
查看>>
sqlserver全文检索
查看>>
C# 语言规范_版本5.0 (第13章 接口)
查看>>
静态库 调试版本 和发布版本
查看>>