通过反汇编简要描述char|通过反汇编简要描述char *str和char str[]的区别以及调用printf输出字符串
结论:
假设以下代码存在于函数内部,即为初始化局部变量
- char *pStr = "aaaaa";
- char arrayStr[] = "aaaaa";
char arrayStr[] = "aaaaa";
char *s = "abcd"str = "bbbbbb";
//error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!将常量字符串的地址赋值给不可被修改的数组首地址
str = s;
//error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 将指向字符的指针赋值给不可被修改的数组首地址
- 将pStr或arrayStr作为printf参数时,实际上都是将字符数组的地址作为参数,此时如果格式化字段为%d就是打印这个地址,若是%c就打印字符数组。
int printf(const char * formal ,[optional],[optional],[optional]...);
分析:
- 初始化一个字符指针指向一个字符数组
linux >>> gcc-Og-opTest-fno-stack-protectorpTest.c //编译源文件
linux >>> objdump -d -pTest.c//查看源文件反汇编代码
int pTest(){
char *a = "aaaaaa";
printf("%s",p);
}0000000000400546 :
400526:48 83 ec 08sub$0x8,%rsp
40052a:be d4 05 40 00mov$0x4005d4,%esi
40052f:bf db 05 40 00mov$0x4005db,%edi
400534:b8 00 00 00 00mov$0x0,%eax
400539:e8 c2 fe ff ffcallq400400 40053e:b8 00 00 00 00mov$0x0,%eax
400543:48 83 c4 08add$0x8,%rsp
400547:c3retq
我们看到本段c代码初始化了一个指向字符的指针,并将一个形如"aaaaa"的字符数组赋值给这个指针。
然后观察汇编代码,我们知道x86-64gcc会默认%rdi存放要调用的函数第一个参数,%rsi存放要调用函数的第二个参数。此时反汇编代码直接将0x4005d40赋值给寄存器%esi,0x4005db赋值给寄存器%edi。
【通过反汇编简要描述char|通过反汇编简要描述char *str和char str[]的区别以及调用printf输出字符串】所以我们去查看这两个地址上的数据:
linux > objdump -spTest
Contents of section .rodata:
4005d0 01000200 61616161 61610025 6400....aaaaaa.%d.
推荐阅读
- 2018-02-06第三天|2018-02-06第三天 不能再了,反思到位就差改变
- 吃了早餐,反而容易饿(为什么?)
- 父母越不讲道理,孩子反而越优秀!说的是你吗()
- gitlab|gitlab 通过备份还原 admin/runner 500 Internal Server Error
- 改变自己,先从自我反思开始
- leetcode|leetcode 92. 反转链表 II
- 那些反串过的艺人-最是美色如醉人
- 反脆弱性(工作越稳定,人生越脆弱!)
- whlie循环和for循环的应用
- 五一反思