当前位置:  建站>运营/SEO
本页文章导读:
    ▪国际C语言混乱代码大赛代码赏析(一)      国际C语言混乱代码大赛代码赏析(一) 近段时间在看《C专家编程》,里面提到国际C语言混乱代码大赛(The International Obfuscated C Code Contest IOCCC)。IOCCC有许多令人捧腹之处,不管你是自己编.........
    ▪离线升级 VS 2012      离线升级 VS 2012     微软现在的安装程序越来越大,升级还多,且要联网。VS 2012 当然也不例外。     但是,也不是所有的电脑都能联网升级的。     那么,VS 2.........
    ▪移植uCOS-II到Cortex-M3平台      本文的目的是希望读者能够通过本文的内容掌握移植uCOS-II 的规范方法。如果只是需要移植文件,可以直接去Micriμm的官网上下载。 移植uCOS-II,主要的移植工作是编写如下三个文件: OS_CPU.........

[1]国际C语言混乱代码大赛代码赏析(一)
    来源: 互联网  发布时间: 2013-10-31

国际C语言混乱代码大赛代码赏析(一)

近段时间在看《C专家编程》,里面提到国际C语言混乱代码大赛(The International Obfuscated C Code Contest IOCCC)。IOCCC有许多令人捧腹之处,不管你是自己编写还是时候分析获胜者的代码,都能够以令人惊讶的方式扩展你的知识。通常有10种类型的获胜者:“对规则的最奇怪的滥用”,“最具创意的源代码布局”,“最简单的单行代码”等。综合性的“最佳上镜”奖授予最难阅读、行为最为古怪(但能够运行)的C程序的作者。下面我们来欣赏并分析1987年,贝尔实验室的David Korn提交的获奖代码:

main() {printf(&unix["\021%six\012\0"], (unix)["have"] + "fun" - 0x60);}

这段代码打印出什么东西?(提示:和“have fun无关”)。

首先看一段代码: 

#include 
int main() 
{ 
	int a[5]={1,2,3,4,5}; 
	printf("%d\n",3[a]); 
	return 0; 
} 
在C语言中,其实数组的引用可以3[a]这样的形式的,等价于a[3]。再看下面一段代码: 
#include 
int main() 
{ 
	int a[5]={1,2,3,4,5},i=4; 
	printf("%d\n",3[a]); 
	printf("%d\n",i[a]); 
	return 0; 
} 
这样的表示也是可以的。i[a]实际上相当于a[4]了。再看下面一段代码: 
#include 
int main() 
{ 
	printf("%d\n",unix); 
	return 0; 
} 
为什么我没有定义unix也能打印出来呢? 原因是unix被编译器内定为一个宏。相当于#define unix 1 这样打印出来1。下面来解释一下这个问题. 
#include 
int main() 
{ 
	printf("%c\n",(unix)["have"]); 
	return 0; 
} 
这里的unix相当于1 ,那么unix["have"]相当于 "have"[1] 我们都知道"have"是个字符数组。那么 "have"[1]就相当于引用这个"have"数组下标为1的字符了,实际上就是a;:
#include 
int main() 
{ 
	printf("0x%x",'a'); 
	return 0; 
} 
a的asc码的16进制表示为0x61。(unix)["have"]+"fun"-0x60就相当于0x61-0x60+"fun"相当于 0x01+"fun" ,相当于字符指针后移并指向"un"了 。这样后面的部分解释完了。
#include 
int main() 
{ 
	printf(&unix["\021ix\012\0"]); 
	return 0; 
} 
我们首先把%s去掉。%s实际上是刚刚讲过的"un"的格式。我们知道unix宏的值 是1,那么
printf(&unix["\021ix\012\0"]);
相当于
printf(&1["\021ix\012\0"]);
根据上贴我说的 1["have"]这个形式,同理能得到:
printf(&"\021ix\012\0"[1]);
这个形式了。这个引用和上面的有所区别区别在于&。那么一个字符数组从它的下标为1 的元素取地址就可以得到一个字符串指针。还原回去相当于
printf(&"\021%six\012\0"[1],"un");
也就是说把第一个元素跳过去了把\021跳了过去。相当于:
printf("%six\012\0","un")

\012 是asc码里的回车。这个串相当于:

printf("%six\n\0","un");

至此 这个问题解决了...

总结:该代码主要应用了x[a]和指针运算等一些知识,对数组和指针的理解有很大的帮助!

作者:ce123 发表于2013-6-11 9:40:29 原文链接
阅读:92 评论:3 查看评论

    
[2]离线升级 VS 2012
    来源: 互联网  发布时间: 2013-10-31
离线升级 VS 2012


    微软现在的安装程序越来越大,升级还多,且要联网。VS 2012 当然也不例外。
    但是,也不是所有的电脑都能联网升级的。
    那么,VS 2012 如何升级呢?

VS2012.2.exe /layout


作者:hadstj 发表于2013-6-12 19:57:07 原文链接
阅读:0 评论:0 查看评论

    
[3]移植uCOS-II到Cortex-M3平台
    来源: 互联网  发布时间: 2013-10-31

本文的目的是希望读者能够通过本文的内容掌握移植uCOS-II 的规范方法。如果只是需要移植文件,可以直接去Micriμm的官网上下载。

移植uCOS-II,主要的移植工作是编写如下三个文件:

OS_CPU.H

OS_CPU_C.C

OS_CPU_A.ASM

下面就按照这三个文件的顺序来介绍。本文以STM32F107+RealView Compiler 开发环境为例。如果使用的其他的开发环境,个别代码可能需要做些小修改。

OS_CPU.H

OS_CPU.H 的第一部分是定义了一个宏OS_CPU_EXT。这一部分暂时可以先不去管。

#ifdef   OS_CPU_GLOBALS

#define  OS_CPU_EXT

#else

#define  OS_CPU_EXT  extern

#endif

接下来是一系列的类型定义。这一部分的移植需参考RealView Compiler Reference Guide的如下章节:

RealView Compiler Reference Guide->C and C++ Implementation Details->Basic data types

从这里可以得到如下信息。

Type 

Size in bits

Natural alignment in bytes 

char 

8

1   (byte-aligned) 

short 

16

2   (halfword-aligned) 

int 

32

4   (word-aligned) 

long 

32

4   (word-aligned) 

long long

64

8   (doubleword-aligned) 

float 

32

4   (word-aligned)

double 

64

8   (doubleword-aligned) 

long double

64

8   (doubleword-aligned)

All pointers

32

4   (word-aligned)

_Bool

8

1   (byte-aligned) 

根据上面的信息,形成下面的代码:

typedef unsigned char BOOLEAN;
typedef unsigned char INT8U;
typedef signed char INT8S;
typedef unsigned short INT16U; 
typedef signed short INT16S;
typedef unsigned int INT32U;
typedef signed int INT32S;
typedef float FP32; 
typedef double FP64;
typedef unsigned int OS_STK; 
typedef unsigned int OS_CPU_SR; 

上面代码中OS_STK 表示堆栈出栈、入栈的基本数据长度。我们知道Cortex-M3 的所有堆栈操作都是以字为单位的,所以这里为 unsigned int 型。OS_CPU_SR 对应的是程序状态寄存器PSRs,自然也是unsigned int 型。

然后是关于临界区的处理,一般来说我们都喜欢使用第三种方法来实现临界区,这里也不例外。这里多说几句,第一种直接开关中断的实现临界区的方法很少采用,因为这种方法可能将原本关闭了的中断意外的打开。第二种方法是最高效的实现方法,但是这种方法调整了堆栈指针,对于需要利用堆栈指针间接寻址局部变量的系统并不适用。(x86通常采用第二种方法,因为它有单独的寄存器来做局部变量的寻址)第三种方法最保险,虽然效率比第二种方法略低一点。

#define OS_CRITICAL_METHOD 3
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}

#if OS_CRITICAL_METHOD == 3
OS_CPU_SR OS_CPU_SR_Save(void);
void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
#endif

这两个函数可以用汇编(OS_CPU_A.ASM)来编写:
    EXPORT  OS_CPU_SR_Save     
  EXPORT  OS_CPU_SR_Restore
OS_CPU_SR_Save
    MRS     R0, PRIMASK ; Set prio int mask to mask all (except faults)
    CPSID   I
    BX      LR

OS_CPU_SR_Restore
    MSR     PRIMASK, R0
  BX      LR

也可以通过C代码(OS_CPU_C.C)中插入汇编的方式来实现:
__asm OS_CPU_SR OS_CPU_SR_Save(void)
{
    MRS     R0, PRIMASK ; Set prio int mask to mask all (except faults)
    CPSID   I
    BX      LR
}
__asm void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr)
{
    MSR     PRIMASK, R0
    BX      LR
}

上面的代码利用的RealView Compiler 的特殊功能(Embedded assembler),如需进一步的信息,可以参考RealView Compiler Reference Guide中Using the Inline and Embedded Assemblers这一章的内容。

然后是堆栈增长方向,ARM Cortex-M3 的堆栈是倒生的:

#define OS_STK_GROWTH 1

任务切换,OSCtxSw()在OS_CPU_A.ASM 中定义:

#define OS_TASK_SW() OSCtxSw()

最后是一些函数原型声明:

void OSCtxSw(void);
void OSIntCtxSw(void);
void OSStartHighRdy(void);
void OS_CPU_PendSVHandler(void);
void OS_CPU_SysTickHandler(void);
OS_HOOK.C

在原本uCOS-II 的移植代码中是没有这个文件的。由于下面这9个函数的函数体基本都是空的,并且移植时几乎不需要更改,所以我就将其拿出到一个单独的文件中来了。

OSInitHookBegin()

OSInitHookEnd()

OSTaskCreateHook()

OSTaskDelHook()

OSTaskIdleHook()

OSTaskStatHook()

OSTaskSwHook()

OSTCBInitHook()

OSTimeTickHook()

这9个函数的代码都很简单,下面是代码,不多介绍。

#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void  OSInitHookBegin (void)
{
	#if OS_TMR_EN > 0 
		OSTmrCtr = 0; 
	#endif
}
#endif

#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void  OSInitHookEnd (void)
{
}
#endif

#if OS_CPU_HOOKS_EN > 0
void  OSTaskCreateHook (OS_TCB *p_tcb)
{
#if OS_VIEW_MODULE > 0
    OSView_TaskCreateHook(p_tcb);
#else
    (void)p_tcb ; /* Prevent compiler warning  */
#endif
}
#endif

#if OS_CPU_HOOKS_EN > 0
void  OSTaskDelHook (OS_TCB *p_tcb)
{
    (void)p_tcb ; /* Prevent compiler warning  */
}
#endif

#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251
extern volatile unsigned long	wdg_clr_flag;
void  OSTaskIdleHook (void)
{
}
#endif

#if OS_CPU_HOOKS_EN > 0
void      
    
最新技术文章:
▪SQVI和SAP查询QUERY的区别和使用注意事项    ▪彻底理解Cisco/Linux/Windows的IP路由    ▪Exchange 2010 处于禁止发送用户自动收到来自IT...
▪MB_CHANGE_DOCUMENT使用方法    ▪ALV的html表头    ▪【译】如何精确判断最终用户响应时间过长的...
▪apache2.4.4启用deflate压缩    ▪使用vmware 配置centos 6.0+ 网络出现的各种问题...    ▪十句话教你学会Linux数据流重定向
▪centos6.x已经安装的系统添加图形界面    ▪Linux查看CPU和内存使用情况    ▪win7问题解决,凭据管理器和无法访问,不允...
▪Dynamics CRM 2013 初体验(4):不再被支持的功...    ▪win7下制作ubuntu系统安装启动盘和U盘安装ubuntu...    ▪Linux cp -a用法
▪Windows Server时间服务器配置方法    ▪Tomcat+memcached实现Session共享    ▪Linux修改系统环境变量PATH路径的方法
▪Citrix 服务器虚拟化之二十七 XenApp6.5发布服务...    ▪搭建本地Ubuntu 镜像服务器    ▪Create local metadata resource of yum
▪tsm ANS0326E问题处理    ▪Windows SVN变化邮件通知(Python2.7实现)    ▪linux下的内核测试工具——perf使用简介
▪Nginx TCP Proxy模块的编译安装    ▪OSX: SSH密钥使用日记(2)    ▪OSX: SSH密钥使用日记(1)
▪Manually start and stop Oracle XE in Ubuntu    ▪Disable autostart of Oracle-xe in Ubuntu    ▪tar命令-linux
▪xtrabackup-2.1.2-611安装    ▪无废话ubuntu 13.4文件共享配置    ▪Unix文本处理工具之sed
▪hpux 操作系统 磁带备份与恢复    ▪HP DL360 G7通过iLO部署系统    ▪Redhat 6.0中VNC Server的配置方法
▪hpux 操作系统磁带备份与恢复    ▪用C++编程调用libvirt的API来创建KVM虚拟机    ▪hpux- hp小型机日常硬件故障处理case(一)
▪web集群时session同步的几种方法(统计)    ▪inux常用命令大全    ▪BAT 批处理实现循环备份N天文件夹
▪BIND9私有DNS服务器小环境搭建实验    ▪Exchange2013增量备份    ▪OSSEC Monitor your App log file
▪《深入理解Nginx》阅读与实践(三):使用upstre...    ▪如何给Fedora 15创建磁盘分区    ▪Packet Sniffer Code in C using sockets
▪Error, some other host already uses address    ▪修改uCOS_II以实现“优先级+时间片”联合调度    ▪weblogic开发模式与生产模式介绍
▪Wireshark 高级特性    ▪ubuntu13.04版本下安装RabbitVCS,类似windows的Tortoi...    ▪Apache 一台主机绑定多个域名及虚拟主机
▪linux安全设置    ▪RHEL双网卡绑定    ▪Linux shell if参数
▪Windows配置路由时可以指定源地址啦    ▪centos安装vim7.4    ▪S3C2410 实验三——块拷贝、字拷贝(寄存器的...
▪系统运维——日志处理    ▪ip_conntrack缓存neighbour    ▪关键在封装并发出了帧-IP冲突也无所谓
▪weblogic11g 安装——linux 无图形界面    ▪《数据通信与网络》笔记--SCTP    ▪《数据通信与网络》笔记--TCP中的拥塞控制
▪weblogic11g 安装集群 —— win2003 系统、单台主...    ▪weblogic11g 节点管理器 nodemanager    ▪Citrix 服务器虚拟化之二十六 应用程序虚拟化...
▪如何将windows下的文件夹挂载到linux虚拟机下    ▪在64位AIX6.1下安装SAP JCo    ▪Outlook启动时提示“找不到文件Outlook.pst文件”...
▪weblogic8.1 登陆5 ip 限制    ▪weblogic 内存 及 内存溢出    ▪手把手教你在Windows端搭建Redmine项目管理软件
▪启动及重新启动nginx,重启nginx后丢失nginx.pid问...    ▪Win7实现快速启动栏并实现靠左边的终极操作...    ▪《深入理解Nginx》阅读与实践(二):配置项...
▪显示grub引导菜单    ▪nagios监控主机    ▪linux各种数据流重定向
▪centOS安装chrome浏览器    ▪Slackware 14 安装完全指南    ▪SharePoint 2013的100个新功能之内容管理(三)
▪Citrix 服务器虚拟化之二十一 桌面虚拟化之部...    ▪[问,ask]ubuntu13.04安装vncserver后只显示桌面,不显...    ▪Win7中IIS出现“HTTP 错误 404.17 - Not Found 请求的...
▪CentOS快速安装最新版本的SaltStack    ▪CentOS 6.4 快速安装Nginx笔记    ▪磁盘管理——RAID 0
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3