Cortex-M3平台C语言调用汇编程序的方法

步骤如下:
1:
新建一ASM文件,在该文件开头加入:
AREA AsmTest, CODE, READONLY
THUMB
PRESERVE8
export AEM_Test ;
在此声明一个可全局引用的标号即该函数名
ASM_Test ;
顶格写
... ;
函数实现
...
END
2:
把该ASM文件添加到项目;
3:
在使用该汇编代码之前现在使用该汇编函数的C文件中声明这个汇编的函数;
void ASM_Test(void);
然后即可调用该函数。

示例:

/******************************************

*test.c

******************************************/

#include <stdio.h>

extern void strcopy(char *d, const char *s);

int main(void)

{

const char *srcstr = "first string - source";

char dststr[] = "second string - destination";

/* dststr is an array since we're going to change it */

printf("before copying:\n");

printf(" '%s'\n '%s'\n",srcstr,dststr);

strcopy(dststr,srcstr);

printf("after copying:\n");

printf(" '%s'\n '%s'\n",srcstr,dststr);

return 0;

}




;;******************************************

;;*strcopy.s

;;******************************************

AREA SCopy, CODE, READONLY

THUMB
PRESERVE8

EXPORT strcopy

strcopy

; r0 points to destination string

; r1 points to source string

LDRB r2, [r1],#1 ; load byte and update address

STRB r2, [r0],#1 ; store byte and update address;

CMP r2, #0 ; check for zero terminator

BNE strcopy ; keep going if not

MOV pc,lr ; Return

END

Posted in 技术 | Leave a comment

把基于IAR的工程移植到MDK

我用过的IDE能够评为第一烂应该是ZSPIDE,这个IDE之烂完全超出你的想象。界面设计的不是一般的难看,使用起来不是一般的难使用,调试环境不是一般的BT,总之,我怀疑这个工具是专门设计用来折腾程序员的。

这几日由于需要调试一颗通信芯片,我用到了传说中的Cortex-M3 内核的ARM微控制器STM32F103ZET6,刚开始我用IAR来做开发,原因很简单,我使用的这个板子有一个(有且只有一个)示例是基于IAR的。安装好了IAR,阅读了入门手册,开始干活。我发现我稍微修改下代码或者重新建立个工程死活编译不了,错误多多。而且这个玩意的设计也很不人性化,调试起来也比较麻烦。奶奶的,隐约之中我觉得我可能碰到人生第二个最烂的IDE了。折腾了一天决定放弃这个很不友好的东西,转向MDK

MDK设计的确实不错,以前做设计开发的时候曾经使用过这个东西,留下的印象还蛮不错的。安装了MDK4.0.0d for ARM, 下一步就是把基于IAR的工程移植到新的MDK开发环境下。这个工作本来是很简单的,但是涉及到一段处理器初始化的代码使得问题有点复杂。不过也没有多大难度,看来看有关手册,修改下有关代码即可。

过程如下(引用网络上一段描述):

不管是IAR还是MDK,编程时使用的都是STM32的固件函数库,唯一不同的是启动文件。RVMDK在建立STM32工程时会自动创建启动文件 STM32F10x.s,而IAR使用的启动文件是cortexm3_macro.s。此外,两者对中断向量表的管理也不一样。

在移植STM32工程时首先要检查IAR工程中是否使用了中断。方法是要看工程中stm32f10x_it.c文件内的各中断函数是否为空函数,中断函数为空说明没有使用中断;否则若中断函数有修改并且在main函数中对NVIC进行了设置,则说明使用了中断。

下面分没有使用中断和使用了中断这两种情况分别介绍移植方法。

工程不使用中断:

没使用中断时的移植较为简单,此时还可以使用RVMDK自动创建的启动文件STM32F10x.s,只要把IAR工程project文件夹中的 stm32f10x_conf.hstm32f10x_it.cstm32f10x_it.hmain.c等文件复制到建立好的RVMDK工程目录下,然后为RVMDK工程添加使用到的库函数文件即可。

工程使用中断:

如果IAR工程中使用了NVIC时,在MDK下就不能再使用自动生成的STM32F10x.s启动文件了,但可以用IAR工程中的启动文件 cortexm3_macro.sstm32f10x_vector.s来替换。

以下为操作步骤:

第一步 在MDK中建立工程,然后将启动文件cortexm3_macro.sstm32f10x_vector.s复制到建立好的工程目录下。并在工程文件中将MDK自动建立的启动文件 STM32F10x.s删除,用以上两个文件替换。注意:这两个文件在IAR环境下开发的时候可能使用到IAR编程语言扩展和编译器相关的一些细节会导致编译不过,这是就要相应的修改源代码,例如:

cortexm3_macro.s文件开头是这样的:

SECTION .text:CODE(2)

; Exported functions

EXPORT __WFI

EXPORT __WFE

EXPORT __SEV

学过ARM汇编的都知道这个不是标准ARM汇编的代码,应该相应的修改为:

THUMB

REQUIRE8

PRESERVE8

AREA |.text|, CODE, READONLY, ALIGN=2

stm32f10x_vector.s文件修改的方法与上相同。

第二步 将IAR工程project文件夹中的相关头文件和源代码文件复制到MDK工程目录内。

第三步 为ADC_MDK工程添加使用到的库函数文件,然后进行编译。

即可。



Posted in 技术 | Leave a comment

一种实现阶乘的另类方法

代码如下:

double fun(double x)
{
int i; double k, sum;
k=x; i=2; sum=0;
sum+=x;
do
{
k *= x / i;
sum += k;
i++;
}
while(i <= x);
return sum;
}
void main(int argc, char* argv[])
{
int x;
scanf("%d",&x);
printf("%.2f\n",fun(x));
}

实现功能是:x+(x^2/2!)+(x^3/3!)+……(x^n/n!)

Posted in 技术 | Leave a comment

结识朋友

这是一个很大的话题,

  这个问题要根据你的个人情况。性格、爱好、经历、职业等的不同,决定了不同的人对朋友圈子的要 求是不一样的。我个人爱好广泛,既喜欢独处,又喜欢热闹;有时很古板,有时开起玩笑来也是云里雾里的。人无完人,我交朋友是看他的长处,只要他并没有什么 太违背社会基本公德的地方,有一点长处或和自己有臭味相投的地方,我都愿意和他交往。当然了,根据对方的不同情况,来往的多少也是不同的。
  友善,诚恳待人。用心与别人真诚沟通。
  善于接纳别人的不同意见,非原则的问题上求大同存小异。
  我本善良,播下善良的种子,一定会有美好的收获。因为,谁种下仇恨他自己迟早都会遭殃!
  真诚的对待别人别人也会真诚地对待你。
  放宽胸怀,主动交友,别等别人跟你交往,自己要主动。

Posted in 生活 | Leave a comment

2G和3G的鉴权系统

2GGSM系统使用三种算法用于鉴权和加密的目的,这些处算法是A3A5A8A3被用于鉴权,A8用于产生加密密钥以及A5用于加密。

  算法A3A8位于SIM卡模块和鉴权中心中,A5位于移动台和BTS中。

  运营者开始使用安全功能之前,移动用户已经在鉴权中心被创建。以下是创建用户所需要的信息:

  (1)用户的IMSI

  (2)用户的Ki

  (3)使用的算法版本

  同样的信息也存储在移动用户的SIM卡中。GSM安全功能的基本原理是比较存储在网络中的数据和存储在用SIM卡中的数据。IMSI号码是移动用户的唯一识别码,Ki 是一个长度为32位十六进制数的鉴权密钥,A3A8算法使用这些数字作为鉴权的基本参数。鉴权吕心产生能用于一个事务处理期间、所有的安全性目的的信息。这个信息称为鉴权数据组。

  2GGSM鉴权数据组由三个数字组成:

  (1RAND

  (2SRES

  (3KC.

  RAND是一个随机数,SRES(签字应答)是算法A3在一定源信息基础上产生的结果,KC A8在一定源信息的基础上产生的加密密钥。

  鉴权数据组中的三个值彼此相互联系,即某个RANDKC 通过某种算法总是产生某个SRES和一个KC

VLR 拥有这类三个值的组合时,就可以启动移动用户的鉴权过程,VLR通过BSS以送随机数RAND至移动台中的SIM卡。由于SIM拥有和网络方产生数组使用 的完全相同的算法,SIM收到的随机数通过算法应该产生与网络方产生的SRES值完全相同。如果鉴权数据中的SRES与移动如计算和发送的SRES一样的话,那么鉴权过程就成功了。2G鉴权3元组包括的元素:RANDRandom Number, SRES( Signed Response), Kc( Ciphering Key)

3G鉴权5元组包括的元素:RANDRandom Number, XRES( Expected Response ), IK(Integrity Key ), CK(Cipher Key), AUTN(Authentication Token)

 3G鉴权比2G增强主要体现在以下两个参数:

AUTN:增加了终端对网络侧合法性的鉴权。

IK3G鉴权过程不仅可生成加密密钥CK,而且可生成完整性密钥IK,且3G鉴权是双向鉴权。

 3G鉴权中的CKIK参数不在空中接口上传送。原因:密钥只要被传送,就有被窃听的危险,因此不能在风险性大的网络上传送,空中接口的风险性大,不能传送密钥:CKIK用于实现手机和RNC之间的信息保护,被保护之前的空口消息和用户数据都是明文传送的,因此,如果CKIK也在空口中传送,则必定是明文方式,有极大的安全风险。

 3G鉴权算法的核心算法是AES算法(Rijndael)。

Posted in 技术 | Leave a comment

C语言enum 测试

有这样一个关于C语言enum的测试程序:

#include <stdio.h>
#include <stdlib.h>

enum season
{
spring, summer = 120, fall = 116, winter,
};

typedef enum weekday
{
monday,
tuesday,
wednesday,
thursday,
friday,
saturday,
sunday,
}weekday_t;

int main(int argc, char *argv[])
{
/* season */
printf("%d \n", spring); // 0
printf("%d, %c \n", summer, summer); // 120, x
printf("%d \n", fall+winter); // 233

enum season mySeason=winter;
if(winter==mySeason)
printf("mySeason is winter \n"); // mySeason is winter

int x=100;
if(x==summer)
printf("x is equal to summer\n"); // x is equal to summer
else
printf("x is not equal to summer\n");

printf("%d bytes\n", sizeof(spring)); // 4 bytes

/* weekday */
printf("sizeof weekday is: %d \n", sizeof(weekday_t)); //sizeof weekday is: 4

weekday_t today = saturday;
printf("today is %d\n", today);  //5
weekday_t tomorrow;
if(today == monday)
tomorrow = tuesday;
else
tomorrow = (weekday_t) (today + 1); //remember to convert from int to Weekday

printf("tomorrow is %d\n", tomorrow);

weekday_t* weekptr;
weekptr = &today;
if (*weekptr != 5)
printf("this day is not saturday\n");
else
printf("this day is saturday\n");

system("PAUSE");
return 0;
}

注意enum类型最后一个元素后面的逗号,我发现添加这个逗号也行,不添加的话也没有问题。很奇怪?查阅C99手册,在第6.7.2.3 Tags 章节里面有这样的说明:

A type specifier of the form
struct-or-union identifieropt { struct-declaration-list }
or
enum identifier { enumerator-list }
or
enum identifier { enumerator-list , }
declares a structure, union, or enumerated type. The list defines the structure content,union content, or enumeration content. If an identifier is provided) the type specifier also declares the identifier to be the tag of that type.

这就意味着上述两种定义方式都是合法的。

Posted in 技术 | Leave a comment

GSM加密系统

GSM 主要使用了三种加密演算法:A5 是stream-cipher(注:以网路电话为例,虽然便利,但它以网路作为传输媒介,很容易被第三者窃听,因此在这些规格中均有定义保护封包的技术如PGP、IPSec 等,这些方式都是以块状密码系统(Block Cipher System)加密资料,然而块状密码系统极为复杂且耗时,将它使用在即时系统中可能造成封包传送上的延误。而串流密码系统(Stream Cipher System)有别于块状密码系统,是种架构相当简单且加密速度非常快速的密码系统,非常适用处理即时资料,目前在无线通讯GSM 系统中的加密演算法A5 即是使用此种系统架构)、A3 是authentication algorithm 和A8 为key agreement algorithm。其中A3 与A8 并没有在GSM 标准规范中被定义,而只有提到它们两者的外部介面该如何使用与统一。每家Operator 可以选择自己想用的加密演算法设计,然而大部分的Operators 都采用在GSM MoU 中提出的COMP128 演算法系统。虽然这个演算法没有被公开发表过,不过其相关说明仍可以在此找到。而且也被人尝试破解分析过,因为这个破解可以解出手机与网路间的Master Key,因此可以在网路上复制一个你的GSM 手机身份出来。

A5 演算法是GSM 标准规范中的一部分,但是它从来没有被公开过技术内容与细节。 A5 演算法有两个版本:A5/1 是strong 版本,有出口限制;A5/2 是weak 版本,没有出口限制。 A5/1 与A5/2 两个演算法的正确设计后来被Marc Briceno、Ian Goldberg 和David Wagner 用逆向工程给破解出来。

下面粘贴一个Marc Briceno、Ian Goldberg 和David Wagner 用逆向工程给破解出来的源代码文件:

/*
* A pedagogical implementation of A5/1.
*
* Copyright (C) 1998-1999: Marc Briceno, Ian Goldberg, and David Wagner
*
* The source code below is optimized for instructional value and clarity.
* Performance will be terrible, but that's not the point.
* The algorithm is written in the C programming language to avoid ambiguities
* inherent to the English language. Complain to the 9th Circuit of Appeals
* if you have a problem with that.
*
* This software may be export-controlled by US law.
*
* This software is free for commercial and non-commercial use as long as
* the following conditions are aheared to.
* Copyright remains the authors' and as such any Copyright notices in
* the code are not to be removed.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The license and distribution terms for any publicly available version or
* derivative of this code cannot be changed.  i.e. this code cannot simply be
* copied and put under another distribution license
* [including the GNU Public License.]
*
* Background: The Global System for Mobile communications is the most widely
* deployed cellular telephony system in the world. GSM makes use of
* four core cryptographic algorithms, neither of which has been published by
* the GSM MOU. This failure to subject the algorithms to public review is all
* the more puzzling given that over 100 million GSM
* subscribers are expected to rely on the claimed security of the system.
*
* The four core GSM algorithms are:
* A3        authentication algorithm
* A5/1        "strong" over-the-air voice-privacy algorithm
* A5/2        "weak" over-the-air voice-privacy algorithm
* A8        voice-privacy key generation algorithm
*
* In April of 1998, our group showed that COMP128, the algorithm used by the
* overwhelming majority of GSM providers for both A3 and A8
* functionality was fatally flawed and allowed for cloning of GSM mobile
* phones.
* Furthermore, we demonstrated that all A8 implementations we could locate,
* including the few that did not use COMP128 for key generation, had been
* deliberately weakened by reducing the keyspace from 64 bits to 54 bits.
* The remaining 10 bits are simply set to zero!
*
* See http://www.scard.org/gsm for additional information.
*
* The question so far unanswered is if A5/1, the "stronger" of the two
* widely deployed voice-privacy algorithm is at least as strong as the
* key. Meaning: "Does A5/1 have a work factor of at least 54 bits"?
* Absent a publicly available A5/1 reference implementation, this question
* could not be answered. We hope that our reference implementation below,
* which has been verified against official A5/1 test vectors, will provide
* the cryptographic community with the base on which to construct the
* answer to this important question.
*
* Initial indications about the strength of A5/1 are not encouraging.
* A variant of A5, while not A5/1 itself, has been estimated to have a
* work factor of well below 54 bits. See http://jya.com/crack-a5.htm for
* background information and references.
*
* With COMP128 broken and A5/1 published below, we will now turn our attention
* to A5/2. The latter has been acknowledged by the GSM community to have
* been specifically designed by intelligence agencies for lack of security.
*
* We hope to publish A5/2 later this year.
*
* -- Marc Briceno    <marc@scard.org>
*    Voice:        +1 (925) 798-4042
*
*/

#include <stdio.h>
#include <stdlib.h>

/* Masks for the three shift registers */
#define R1MASK    0x07FFFF /* 19 bits, numbered 0..18 */
#define R2MASK    0x3FFFFF /* 22 bits, numbered 0..21 */
#define R3MASK    0x7FFFFF /* 23 bits, numbered 0..22 */

/* Middle bit of each of the three shift registers, for clock control */
#define R1MID    0x000100 /* bit 8 */
#define R2MID    0x000400 /* bit 10 */
#define R3MID    0x000400 /* bit 10 */

/* Feedback taps, for clocking the shift registers.
* These correspond to the primitive polynomials
* x^19 + x^5 + x^2 + x + 1, x^22 + x + 1,
* and x^23 + x^15 + x^2 + x + 1. */
#define R1TAPS    0x072000 /* bits 18,17,16,13 */
#define R2TAPS    0x300000 /* bits 21,20 */
#define R3TAPS    0x700080 /* bits 22,21,20,7 */

/* Output taps, for output generation */
#define R1OUT    0x040000 /* bit 18 (the high bit) */
#define R2OUT    0x200000 /* bit 21 (the high bit) */
#define R3OUT    0x400000 /* bit 22 (the high bit) */

typedef unsigned char byte;
typedef unsigned long word;
typedef word bit;

/* Calculate the parity of a 32-bit word, i.e. the sum of its bits modulo 2 */
bit parity(word x)
{
x ^= x>>16;
x ^= x>>8;
x ^= x>>4;
x ^= x>>2;
x ^= x>>1;
return x&1;
}

/* Clock one shift register */
word clockone(word reg, word mask, word taps)
{
word t = reg & taps;
reg = (reg << 1) & mask;
reg |= parity(t);
return reg;
}

/* The three shift registers.  They're in global variables to make the code
* easier to understand.
* A better implementation would not use global variables. */
word R1, R2, R3;

/* Look at the middle bits of R1,R2,R3, take a vote, and
* return the majority value of those 3 bits. */
bit majority()
{
int sum;
sum = parity(R1&R1MID) + parity(R2&R2MID) + parity(R3&R3MID);
if (sum >= 2)
return 1;
else
return 0;
}

/* Clock two or three of R1,R2,R3, with clock control
* according to their middle bits.
* Specifically, we clock Ri whenever Ri's middle bit
* agrees with the majority value of the three middle bits.*/
void clock()
{
bit maj = majority();
if (((R1&R1MID)!=0) == maj)
R1 = clockone(R1, R1MASK, R1TAPS);
if (((R2&R2MID)!=0) == maj)
R2 = clockone(R2, R2MASK, R2TAPS);
if (((R3&R3MID)!=0) == maj)
R3 = clockone(R3, R3MASK, R3TAPS);
}

/* Clock all three of R1,R2,R3, ignoring their middle bits.
* This is only used for key setup. */
void clockallthree()
{
R1 = clockone(R1, R1MASK, R1TAPS);
R2 = clockone(R2, R2MASK, R2TAPS);
R3 = clockone(R3, R3MASK, R3TAPS);
}

/* Generate an output bit from the current state.
* You grab a bit from each register via the output generation taps;
* then you XOR the resulting three bits. */
bit getbit()
{
return parity(R1&R1OUT)^parity(R2&R2OUT)^parity(R3&R3OUT);
}

/* Do the A5/1 key setup.  This routine accepts a 64-bit key and
* a 22-bit frame number. */
void keysetup(byte key[8], word frame)
{
int i;
bit keybit, framebit;

/* Zero out the shift registers. */
R1 = R2 = R3 = 0;

/* Load the key into the shift registers,
* LSB of first byte of key array first,
* clocking each register once for every
* key bit loaded.  (The usual clock
* control rule is temporarily disabled.) */
for (i=0; i<64; i++)
{
clockallthree(); /* always clock */
keybit = (key[i/8] >> (i&7)) & 1; /* The i-th bit of the key */
R1 ^= keybit; R2 ^= keybit; R3 ^= keybit;
}

/* Load the frame number into the shift
* registers, LSB first,
* clocking each register once for every
* key bit loaded.  (The usual clock
* control rule is still disabled.) */
for (i=0; i<22; i++)
{
clockallthree(); /* always clock */
framebit = (frame >> i) & 1; /* The i-th bit of the frame #
*/
R1 ^= framebit; R2 ^= framebit; R3 ^= framebit;
}

/* Run the shift registers for 100 clocks
* to mix the keying material and frame number
* together with output generation disabled,
* so that there is sufficient avalanche.
* We re-enable the majority-based clock control
* rule from now on. */
for (i=0; i<100; i++)
{
clock();
}

/* Now the key is properly set up. */
}

/* Generate output.  We generate 228 bits of
* keystream output.  The first 114 bits is for
* the A->B frame; the next 114 bits is for the
* B->A frame.  You allocate a 15-byte buffer
* for each direction, and this function fills
* it in. */
void run(byte AtoBkeystream[], byte BtoAkeystream[])
{
int i;

/* Zero out the output buffers. */
for (i=0; i<=113/8; i++)
AtoBkeystream[i] = BtoAkeystream[i] = 0;

/* Generate 114 bits of keystream for the
* A->B direction.  Store it, MSB first. */
for (i=0; i<114; i++)
{
clock();
AtoBkeystream[i/8] |= getbit() << (7-(i&7));
}

/* Generate 114 bits of keystream for the
* B->A direction.  Store it, MSB first. */
for (i=0; i<114; i++)
{
clock();
BtoAkeystream[i/8] |= getbit() << (7-(i&7));
}
}

/* Test the code by comparing it against
* a known-good test vector. */
void test()
{
byte key[8] = {0x12, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF};
word frame = 0x134;
byte goodAtoB[15] = { 0x53, 0x4E, 0xAA, 0x58, 0x2F, 0xE8, 0x15,
0x1A, 0xB6, 0xE1, 0x85, 0x5A, 0x72, 0x8C, 0x00 };
byte goodBtoA[15] = { 0x24, 0xFD, 0x35, 0xA3, 0x5D, 0x5F, 0xB6,
0x52, 0x6D, 0x32, 0xF9, 0x06, 0xDF, 0x1A, 0xC0 };
byte AtoB[15], BtoA[15];
int i, failed=0;

keysetup(key, frame);
run(AtoB, BtoA);

/* Compare against the test vector. */
for (i=0; i<15; i++)
if (AtoB[i] != goodAtoB[i])
failed = 1;
for (i=0; i<15; i++)
if (BtoA[i] != goodBtoA[i])
failed = 1;

/* Print some debugging output. */
printf("key: 0x");
for (i=0; i<8; i++)
printf("%02X", key[i]);
printf("\n");
printf("frame number: 0x%06X\n", (unsigned int)frame);
printf("known good output:\n");
printf(" A->B: 0x");
for (i=0; i<15; i++)
printf("%02X", goodAtoB[i]);
printf("  B->A: 0x");
for (i=0; i<15; i++)
printf("%02X", goodBtoA[i]);
printf("\n");
printf("observed output:\n");
printf(" A->B: 0x");
for (i=0; i<15; i++)
printf("%02X", AtoB[i]);
printf("  B->A: 0x");
for (i=0; i<15; i++)
printf("%02X", BtoA[i]);
printf("\n");

if (!failed)
{
printf("Self-check succeeded: everything looks ok.\n");
return;
}
else
{
/* Problems!  The test vectors didn't compare*/
printf("\nI don't know why this broke; contact the authors.\n");
exit(1);
}
}

int main(int argc, char *argv[])
{
test();
system("PAUSE");
return 0;
}


Posted in 技术 | Leave a comment

MSC/VLR概述

MSC(Mobile services Switching Centre (Core Network Context))是完成对位于它所服务区域中的移动台进行控制、交换的功能实体,也是蜂窝网与其它公用交换网或其它MSC之间的用户话务的自动接续设备。MSC具备网络接口、公共信令系统和计费等功能;具备BSS-MSC之间的A接口信令系统和无线资源管理、移动性管理等功能;具备建立至被叫移动台的呼叫路由,完成关口MSCGMSC)的功能。
 VLR(
Visitor Location Register)是一个数据库,存储对应MSC所管辖区域中MS的来话、去话呼叫所需检索的信息,例如用户的号码、属性、所处位置区域的识别、向用户提供的服务等参数。

Posted in 技术 | Leave a comment

2012潜台词

上周末和MM去看了这个电影,视觉效果还行,演戏嘛,就是那样。

刚想写点什么,有人已经把潜台词总结好了,转述如下:

1、欧元将大幅升值 取代美元的世界货币地位;

2、意大利人很傻很天真,信上帝不如信春哥;
  3、只有中国这种极权国家才能造出方舟这种绝密超巨型设施;
  4、加州州长还将是一名演员;
  5、中国人在任何时候都能走后门,哪怕你只是认识个看门的民工
  6、有钱就代表有能力,有能力就代表基因优秀,即便是条狗
  7、美国总统永远都是人民的总统
  8、千万别当第三者 第三者的下场都很悲惨
  9、一定要经常收听业余广播电台,哪怕是个疯子在广播
  10、以后的汽车都是声控的,喊口令时其他人必须安静
  11、好莱坞帮中国回答了为何要在雅鲁藏布江上建大坝,看印度瘪三还敢放屁不。

Posted in 生活 | Leave a comment

三目运算符code ex

有如下代码:

#include <stdio.h>
#include <stdlib.h>

typedef enum
{
UHF_BAND=0,
VHF_BAND,
S_BAND
} RF_BAND_TYPE;

RF_BAND_TYPE g_curRFBand = UHF_BAND;

int main(int argc, char *argv[])
{
int ofs_lna, s_lna;

ofs_lna = (g_curRFBand==UHF_BAND)?(s_lna==0)? 0 : (s_lna==1)? -6 : (s_lna==2)? -17 : (s_lna==3)? -22 : -30: 0;

printf("%d\n",ofs_lna);

system("pause");

return 0;

}

试试分析中间三目运算符的语句,比较有趣!提示,从语句后部分分析起来比较简单。

多谢小马哥指点。

Posted in 开源 | Leave a comment