C语言extern引用AT&T汇编中的变量,任意转换类型

今天研究出了一个小问题,在C语言里引用汇编的变量,会是什么结果,汇编中的变量没有像C语言中int类型那样的类型约束,可以把数据当作任何类型处理,那么传到C语言中我们应该当作什么类型处理呢。

换句话说,在汇编里定义变量var,在C语言里引用,我们肯定要用extern声明var外部变量,那么extern后面接什么类型?难道是extern int var么?还是 extern short var

实例:

注意:混合编译的方法,gcc test.s main.c 这样直接用gcc处理汇编和C语言文件就可以自动搞定。

一、

汇编程序:(是的,就这么短小)

.global var #注意现在的汇编器不再要求被C语言引用的变量名前加下划线
.data
var:
.fill 10,4,9 #填充10个单元,每个单元4字节,每个单元的值为9

C语言:

#include <stdio.h>
extern int var; //现在的C语言编译器引用汇编变量可以使用和汇编变量同样的名字,写成_var反而会错误
void main()
{
printf("sizeof(var)=%d\n",sizeof(var));
printf("%d\n", var);
}

程序的输出为

sizeof(int)=4
9

解释很简单,




    		    C语言extern引用AT&T汇编中的变量,任意转换类型

如上图,我只画了四个字节,我填充了10个单元的,每单元占用4字节,意思就是每个9占四个字节。如图,然后C语言里声明为extern int var;就是把前四个字节看作一个int变量取出来,当然是9了。

二、

保持C语言程序和上一个一样,

extern int var;

把汇编语句改成

.fill 10,2,9 #10个单元,每个单元填入9,每单元大小为2B

这就意味着每个单元2字节,每个单元填一个9,我们不改变C语言语句,那么仍将把var看作int型4字节变量,依然是一次取出前4个字节作为var的值。那我们推测一下结果会是什么。

首先每个9占用两字节,内存图应该是这样的,(只画了4字节,后面没画)




    		    C语言extern引用AT&T汇编中的变量,任意转换类型

一次性取出4个字节,就是0x00090009,这玩意儿拿到windows自带计算器里算出来是是十进制的589833,这就是我们的预测值。让我们看下程序结果是不是和我们猜的一样。




    		    C语言extern引用AT&T汇编中的变量,任意转换类型

没错吧,这就是说我们在汇编里定义的变量,来到C语言里可以任意声明为任意类型,从sizeof的输出也能看出,我们把var声明成多大,它就是多大。

三、

我们再试试别的,汇编语句保持和上一个一样,依然是

.fill 10,2,9 #10个单元,每个单元填入9,每单元大小为2B

我们改变C语言语句,把var声明成

extern long long var; //8字节整型

当然,输出语句稍微变下,因为是long long型整数,所以要这么输出printf("%lld\n", var);

#include <stdio.h>
extern long long var;
void main()
{
printf("sizeof(var)=%d\n",sizeof(var));
printf("%lld\n", var);
}

我们还是事先猜测结果,字节太多我不画图了,按照上面的的思路,这次取出8字节当作long long变量var的值,那么应该是0x0009000900090009,化为十进制是2533313445691401。

看看程序运行结果:




    		    C语言extern引用AT&T汇编中的变量,任意转换类型

预测正确。

四、

再来,把var声明为char变量。

#include <stdio.h>
extern char var; #声明为char
void main()
{
printf("sizeof(var)=%d\n",sizeof(var));
printf("%c\n", var);
}

输出语句相应的改变成%c

汇编里面稍微改改填充的数值,因为9是制表符的ASCII码,输出了你也看不到。我们改成填充43

.fill 10,2,43 #10个单元,每个单元填入43(内存实际存储按照二进制来的),每单元大小为2B

注意43的十六进制表示为0x2b,这是加号“+”的ASCII码,

内存里面长成这样




    		    C语言extern引用AT&T汇编中的变量,任意转换类型

C语言会认为var是char型的,取出一个字节当作var的值,也就是把0x2b送给var,我们把var用%c输出,就是输出了0x2b这个ASCII码所代表的字符。就是“+”号。




    		    C语言extern引用AT&T汇编中的变量,任意转换类型

五、

好吧,再这么整下去也没完了,下面用一个数组定义来终结此文吧。

汇编语言代码和上一个一样,

.fill 10,2,43

C语言修改成:

#include <stdio.h>
typedef char CHARARR[20]; //CHARARR是一个类型别名,用它定义的每一个变量都是包含20个字符的数组
extern CHARARR var; //var被定义为CHARARR类型,是一个包含20个元素的char型数组。
void main()
{
printf("sizeof(var)=%d\n",sizeof(var));
int i=0;
while(i<=19)
{
printf("[%c]", var[i]); //用[]括起来更容易看出输出现象
i++;
}
printf("\n");
}

我们让var成为数组,含有20个元素,正好把汇编里面的 10单元x2字节 共计20个字节包括了。

然后用循环逐个输出,为什么要这么做而不用%s呢,因为数组里有很多字节是0x00,这是字符串终止标志。%s会被打断的。

结果如下:




    		    C语言extern引用AT&T汇编中的变量,任意转换类型

可以看到和预计的一样,20个元素以ASCII码 0x2b 0x00 0x2b 0x00。。。。这样的数组顺序挨个输出。

讲完了,C语言和汇编语言结合起来是不是强大到了难以想象的地步,随心所欲操纵内存数据。

本文出自 “Strive For RedHat Inc.” 博客,请务必保留此出处http://mirage1993.blog.51cto.com/2709744/1635436

更多相关文章
  •   1. 下载libmad源码   2. 在目录C:\cygwin\home\Administrator\android-ndk-r4b-windows\android-ndk-r4b\samples\下创建目录jni,并把libmad的源码解压到该目录下,这样mad.h的目录是:C:\cygwin ...
  • 据位于伦敦的安全公司ScanSafe发表的数据显示,今年第2季度微软的IE浏览器中的一个安全漏洞是被黑客用来实施攻击的最多的一个安全漏洞. 这家安全公司称,排名第一的安全漏洞是"Exploit.HTML.Mht".黑客利用微软IE浏览器中的这个安全漏洞就可以在用户计算机上下载和安 ...
  • Given an unsorted array of integers, find the length of the longest consecutive elements sequence. For example,Given [100, 4, 200, 1, 3, 2],The longes ...
  • 一.远程桌面授权 远程桌面授权(RD 授权)以前称为终端服务授权(TS 授权),它能够管理每个设备或用户与远程桌面会话主机(RD 会话主机)服务器连接所需的远程桌面服务客户端访问许可 (RDS CAL).使用 RD 授权在远程桌面授权服务器上安装.颁发 RDS CAL 并跟踪其可用性. 客户端(用户 ...
  • 背景详见<html" target=_blank>Hosts绑定新思路之DNS代理篇>核心内容1. DNS协议解析2. 启动UDP服务,监听53端口3. 根据DB或者文本,进行Hosts解析DNS协议DNS Protocol Overview (推荐)非强详细,但是不怎么 ...
  • 最近几乎每天都有应急响应工作,自己写的一个linux下的webshell查杀小脚本,如果网站文件太多,打包太大,可以用这个脚本查杀一下,然后根据日志和时间再找其他的webshell,如果网站文件比较小,建议打包下来,用 {D盾Web后门查杀V1.2.6版本} 在windows下查杀,查杀脚本下载地址 ...
一周排行
  • www.2cto.com:这是一个好无聊的新闻高啊,把广告删掉后好多了.虽然还是很无聊 NBA总决赛激战正酣,热火对雷霆两支热血青年军之争让“奥布莱恩”杯的归属充满悬念,各种预测满天飞.网友“hnlouis610”不 ...
  • 懒骨头(http://blog.csdn.net/iamlazybone QQ:124774397 青岛) cocos2dx3.0beta2发布了 对于喜欢尝鲜的人来说一定不会错误 哪怕什么都没变之把名字升级了咱也得 ...
  • 表单(Forms)是在网站交互的一个很普通的方法.JSP使表单处理更加简单.在JSP中处理表单的标准方法是定义一个"bean".这个"bean"不是一个完全的Java bean ...
  • 测试网络连接的时间tracert及其其它常用命令   背景: 项目即将上线,给客户开的测试环境客户总说慢(13s响应).但是,本地发布运行时也就300ms以内,于是将项目发布到另一个服务器上测试,测试的结果响应时间是 ...
  • 说起来Validation验证功能,相信大家都不陌生,在应用中,当需要用户交互输入时,开发人员都会加入一些验证代码,这样可以有效的避免应用异常出现,也可以使应用的错误提示信息清晰明了的显示在客户端,有利于异常定位,同 ...
  • JavaScript自动计算价格和全选,价格自增加减,复选框,反选,全选. 如图: 如图: CSS代码 @charset "gb2312"; /* CSS Document */ body{ ma ...
  • apache作为现今web服务器用的最广泛也是最稳定的开源服务器软件,其工作模式有许多中,目前主要有两种模式:prefork模式和worker模式 一.两种模式 prefork模式:     prefork是Unix ...
  • 声明:本文的传统计算机指的是冯若依曼式的存储式计算机. 现在有很多关于人工智能的书籍和资料,我也看过很多,但是我认为那些资料很大意义上是一些算法方面的资料,所谓的智能也只是在算法上寻找突破,可是算法设计得再精妙也还摆 ...
  • 今日,无所不能的金正恩将军在朝鲜航天局宣布,要让朝鲜宇航员登陆太阳.一位美国记者问到,太阳这么热怎么登上去?顿时全场鸦雀无声,大家纷纷议论怎么会问这个问题.这时,金将军缓缓站起来,小手一挥严肃地回答:我们天黑去!说完 ...
  • 系统蓝屏70%是由于内存(病毒)windows蓝屏错误,系统有时候会经常蓝屏,显示一些错误代码,那么这些错误代码是什么意思呢!小编今天特地为大家总结了一些常见的蓝屏错误代码分析和解决办法,需要的朋友可以参考下 系统蓝 ...