char*与char[]-从编译后的汇编代码分析

含义
.text已编译程序的机器代码
.rodata只读数据,如pintf和switch语句中的字符串和常量值
.data已初始化的全局变量
.bss未初始化的全局变量
.symtab符号表,存放在程序中被定义和引用的函数和全局变量的信息
.rel.text当链接器吧这个目标文件和其他文件结合时,.text节中的信息需修改
.rel.data被模块定义和引用的任何全局变量的信息
.debug一个调试符号表。
.line原始C程序的行号和.text节中机器指令之间的映射
.strtab一个字符串表,其内容包含.systab和.debug节中的符号表

 

1、汇编相关段 的说明在上。

2、C源代码,x为char *,y为char []

 

#include <stdio.h>

void main(){

   char *x="xxxx";

   char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097

   printf("%s-----%s",x,y);

   exit(0);

}

deepfuture@deepfuture-laptop:~/private/mytest$ gcc -S testcr.c

 

.file "testcr.c"

.section .rodata

.LC0:

.string "xxxx"#使用char *分配

.LC1:

.string "%s-----%s"

.text

.globl main

.type main, @function

main:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

subl $32, %esp#分配32字节栈空间,根据变量情况分配

movl $.LC0, 24(%esp)#x变量使用指针(4个字节大小),放入栈中,可以看到,变量分配靠近栈空间的尾部

movw $31097, 29(%esp)#字符'yy'移到main程序的栈中,直接将y变量的值放入栈中

movb $0, 31(%esp)#加上NULL标志,表示字符结束 

movl $.LC1, %eax

leal 29(%esp), %edx

movl %edx, 8(%esp)

movl 24(%esp), %edx

movl %edx, 4(%esp)

movl %eax, (%esp)

call printf

movl $0, (%esp)

call exit

.size main, .-main

.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

.section .note.GNU-stack,"",@progbits

 

3、由以上分析可以看出,在MAIN函数中char *分配在只读数据段中,实际使用时,只在程序栈中分配一个指针的空间。char[] 在程序栈中分配空间,然后直接使用movl、movw之类的汇编直接把值放入栈中空间。那么在其它函数中声明的呢,可以从以下程序中看出,仍然如此。

 

#include <stdio.h>

void myprinf(){

   char *x="xxxx";

   char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097

   printf("%s-----%s",x,y);

}

void main(){

   int num=1;

   myprint();

   exit(0);

}

deepfuture@deepfuture-laptop:~/private/mytest$ gcc -S testcr.c

ASM代码:

 

.file "testcr.c"

.section .rodata

.LC0:

.string "xxxx"

.LC1:

.string "%s-----%s"

.text

.globl myprinf

.type myprinf, @function

myprinf:

pushl %ebp

movl %esp, %ebp

subl $40, %esp

movl $.LC0, -16(%ebp)

movw $31097, -11(%ebp)

movb $0, -9(%ebp)

movl $.LC1, %eax

leal -11(%ebp), %edx

movl %edx, 8(%esp)

movl -16(%ebp), %edx

movl %edx, 4(%esp)

movl %eax, (%esp)

call printf

leave

ret

.size myprinf, .-myprinf

.globl main

.type main, @function

main:

pushl %ebp

movl %esp, %ebp

andl $-16, %esp

subl $32, %esp

movl $1, 28(%esp)

call myprint

movl $0, (%esp)

call exit

.size main, .-main

.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"

.section .note.GNU-stack,"",@progbits

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值