c语言的汇编表示 数组,指针和字符串

c语言的汇编表示 数组,指针和字符串

1.
void func(int a[])
{
}
int  main ()
{
	int a[10];
	func(a[1]); //报错 原因:a[1]被当作是一个int类型 ,并不奇怪
	return 0;
}
int  main ()
{
	int a[10];
	func(a[1]); //这样就没有问题
	return 0;
}
void func(int a)
{
}
2.
void func(int a[11])
{
 //居然可以在形参中定义带有大小的数组,吃惊
}
3.
void func1(int a[])
{
}
void func2(int* a)
{
}
int  main ()
{
	int a[10];
	//这两种传参方式在汇编角度没有任何区别,都是传入数组首地址,
	也就是说可以fun1和fun2内更改a[10]的值
	func1(a);
	func2(a);
	return 0;
}
汇编代码
	func1(a);
00BB1963  lea         eax,[ebp-2Ch]  
00BB1966  push        eax  
00BB1967  call        00BB12C6  
00BB196C  add         esp,4  
	func2(a);
00BB196F  lea         eax,[ebp-2Ch]  
00BB1972  push        eax  
00BB1973  call        00BB12C1  
00BB1978  add         esp,4  
所以我可以这样
void func1(int a[])
{
int i=2;
*(a+i)=1;
a[i]=1;
}
void func2(int* b)
{
int i=2;
*(b+i)=1;
b[i]=1;
}
4.
int  main ()
{
	const char* a="abcde"; 
	//为什么可以这么赋值?因为“abcde”实际上就是这个const char*这个类型
	//双引号表示编译器会在常量区存储‘a’'b''c''d''e''\0'
	//然后用你写的"abcde"来表示常量区的那个字符串的首地址
}
同样的你还可以这样
 void func(const char* a)
{
}
int  main ()
{
	func("wa");
}
5.
int  main ()
{
	char* a = (char*)"abcde";
	a[1] = 2;
	//我可以这样吗? 不能,因为常量区的代码是不可改的
	//是真的不能改吗?其实我们可以调用windows提供的api来更改内存权限
	//virtualprotect(),修改字符串之后记得把权限改回来
}
为什么用下面的方式不用更改内存权限
int  main ()
{
	char a[]="dwad";
	a[1] = 2;
}
查看反汇编代码
char a[]="dwad";
002C15A3  mov         eax,dword ptr ds:[002C5C34h]  
002C15A8  mov         dword ptr [ebp-0Ch],eax  
002C15AB  mov         cl,byte ptr ds:[002C5C38h]  
002C15B1  mov         byte ptr [ebp-8],cl  
	a[1] = 2;
002C15B4  mov         eax,1  
002C15B9  shl         eax,0  
002C15BC  mov         byte ptr [ebp+eax-0Ch],2  
寄存器把常量区的字符串复制到了数组中
a[i]=2;修改的其实是栈中的数组里面的值,那当然就可以修改了嘛
我翻看了csdn的文章说
char a[10];
a[0]="hello"这样是错误的
这不是废话吗,char a[10]存储的是char类型,一个字节,而"hello"是地址,占4个字节,能存吗?
这样不就行了
# include<stdio.h>
int  main ()
{
	const char* a[10];
	a[0] = "dwa";
	printf("%p", a[0]);
}
c语言没有字符串类型,这句话应该是对的,java,c#都是c实现的,如果那些语言有字符串类型,那也是假的,无非是把常量区的字符串复制到了其他缓冲区里面
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值