C51几个预编译指令的用法
gcc 预编译指令
gcc 预编译指令
gcc预编译指令是指在编译源代码之前,对代码进行预处理的指令。
这些指令可以用来包含头文件、定义常量、宏和条件编译等。
预处理器会根据这些指令将代码转换为更适合编译器处理的形式。
常见的预编译指令有:
- #include:用于包含头文件。
- #define:用于定义常量和宏。
- #ifdef、#ifndef、#endif:用于条件编译,根据是否已定义某个宏来判断是否编译某段代码。
- #pragma:用于提供编译器特定的指令,例如优化选项等。
使用预编译指令可以提高代码的可读性和可维护性,同时也可以避免一些常见的错误。
但是,过度使用预编译指令也可能导致代码难以理解和调试。
因此,在使用预编译指令时,需要谨慎考虑其影响,并遵循良好的编码习惯。
- 1 -。
c51 条件编译
c51 条件编译C51的条件编译是预处理指令的一种,它允许在编译时根据某些条件选择性地编译代码。
C51条件编译主要有三种形式:1.#ifdef 标识符如果指定的标识符已被#define命令定义,则编译随后的程序段,直到遇到#else或#endif。
如果没有定义该标识符,且存在#else部分,则编译#else后的程序段。
c#ifdef DEBUG// 这部分代码仅在DEBUG被定义时编译#else// 这部分代码仅在DEBUG未被定义时编译#endif2.#ifndef 标识符这与#ifdef相反。
如果指定的标识符没有被#define命令定义,则编译随后的程序段。
如果标识符已被定义,且存在#else部分,则编译#else后的程序段。
c#ifndef RELEASE// 这部分代码仅在RELEASE未被定义时编译#else// 这部分代码仅在RELEASE被定义时编译#endif3.#if 常量表达式如果常量表达式为“真”(非零),则编译随后的程序段。
否则,如果存在#else部分,则编译#else后的程序段。
c#if VERSION > 2// 这部分代码仅在VERSION大于2时编译#else// 这部分代码在其他情况下编译#endif条件编译在多种情况下都很有用,例如:•调试和发布版本:通过定义不同的标识符(如DEBUG和RELEASE),可以在调试和发布版本之间切换。
•多平台支持:可以使用条件编译为不同的平台或硬件配置编写特定的代码。
•功能切换:可以通过条件编译启用或禁用某些功能。
请注意,在使用条件编译时要小心,确保代码的逻辑清晰,并避免创建难以理解和维护的复杂条件结构。
C语言第7章预编译命令
C语言程序设计教程
7.2带参宏定义
如果宏定义串中a 周围的括号被去掉,即: #define ABS(a) a<0?-a:a
则表达式: ABS( lO - 20) 将转换为: 1O – 20 < 0 ? -10 - 20 : 10 – 20
所以须特别注意宏定义中参数的括号问题!!
int a = 1308001,c = 1308002;
float b = 621,d = 612;
Print(Format,"Wangyi",a,b);
Print(Format,"Liwei",c,d);
return 0; 程序运行结果:
}
输出: Wangyi 1308001 621.00 14
Liwei 1308002 612.00
对语句:
printf("%f ",1T+H1R+E1E));;
12
C语言程序设计教程
7.1.2无参宏定义
如果串长于一行,可在行尾用反斜线“\”续行, 如:
#define LONG_STRING "this is a very long\ string that is used as an example"
习惯上宏名用大写字母表示,以便于与变量区 别。但也允许用小写字母。
13
C语言程序设计教程
7.1.2无参宏定义
例7.2 使用宏定义实现格式控制输出。
#include <stdio.h>
#define Print printf
#define Format "%10s%8d%8.2f\n"
Keil C51使用详解
Keil C51使用详解第一章Keil C51开发系统基本知识 (6)第一节系统概述 (6)第二节Keil C51单片机软件开发系统的整体结构 (6)第三节Keil C51工具包的安装 (7)1. C51 for Dos 72. C51 for Windows的安装及注意事项: (7)第四节Keil C51工具包各部分功能及使用简介 (7)1. C51与A51. 72. L51和BL51. 83. DScope51,Tscope51及Monitor51. 84. Ishell及uVision. 9第二章Keil C51软件使用详解 (10)第一节Keil C51编译器的控制指令 (10)1. 源文件控制类 (10)2. 目标文件(Object)控制类: (10)3. 列表文件(listing)控制类: (10)第二节dScope51的使用 (11)1. dScope51 for Dos 112. dScope for Windows 12第三节Monitor51及其使用 (13)1. Monitor51对硬件的要求 (13)2. Mon51的使用 (13)3. MON51的配置 (13)4. 串口连接图: (13)5. MON51命令及使用 (14)第四节集成开发环境(IDE)的使用 (14)1. Ishell for Dos的使用 (14)2. uVision for windows的使用 (15)第三章Keil C51 vs 标准C.. 15第一节Keil C51扩展关键字 (15)第二节内存区域(Memory Areas): (16)1. Pragram Area: (16)2. Internal Data Memory: 163. External Data Memory. 164. Speciac Function Register Memory. 16第三节存储模式 (16)1. Small模式 (16)2. Compact模式 (17)3. large模式 (17)第四节存储类型声明 (17)第五节变量或数据类型 (17)第六节位变量与声明 (17)1. bit型变量 (17)2. 可位寻址区说明20H-2FH.. 18第七节Keil C51指针 (18)1. 一般指针 (18)2. 存储器指针 (18)3. 指针转换 (18)第八节Keil C51函数 (19)1. 中断函数声明: (19)2. 通用存储工作区 (19)3. 选通用存储工作区由using x声明,见上例。
c51的预编译
Keic C51中几个预处理指令【转】2008-11-15 19:42Keic C51中几个预处理指令1.#message用法:#message "message"用途:当编译器编译到#message处会在编译输出栏中输出message消息,这时程序员可以知道编译器已经并且编译了该处,可以用来检查程序是否有编译了此处,或者在此设置一些消息告知程序员。
此条预编译指令相当于C中的#pragma message("消息文本") ,此预编译命令在Keil Compiler也可以支持,效果与#message例如:#ifdef DEBUG_ENABLE#message "IN DEBUG MODE"//可以用来告知程序员程序处于DEBUG模式下#endif这样的message会在uVision的Output Window上显示,而无论有多少个message 输出,编译输出栏都不会有warning或error。
2.#warning用法:#warning "message"用途:与#message类似,区别是当遇到这样的预编译命令会抛出一个警告,若有多个警告则编译输出栏中的warning个数累加。
3.#error用法:#error "message"用途:程序员会在source code中的重要部分加上这个预编译指令,因为编译到了这个地方程序可能会有问题而编译器却无法发现,这时这条预编译指令就产生了作用。
碰到此指令会抛出一个错误,程序将无法通过编译。
以上三条指令用法类似,只是编译的时候抛出的warning级别不一样,程序员可以自己根据严重程度自己设置,三条指令显示的消息可以不用加双引号"",这三条预编译指令只在Keil Compiler上有效。
4.#ifndef/#define/#endif组合作用:防止该头文件被重复引用。
KEIL C51 中 C语言加入汇编语言的使用方法
KEIL C51 中C语言加入汇编语言的使用方法
51单片机2008-06-03 18:20:42 阅读22 评论0字号:大中小
1.通过使用预处理指令#asm 和#endasm来使用汇编语言。
用户编写的汇编语言可以紧跟在#asm之后,而在#endasm之前结束。
如下所示:
#asm
/*汇编源程序*/
#endasm
在#asm和#endasm之间的语句将作为汇编语言的语句输出到由编译器产生的汇编语言文件中。
2.通过使用预处理指令# pragma asm和函数_asm()来使用汇编语言。
在程序的开头加上预处理指令#pragma asm,在该预处理指令之前只能有注释和其它预处理指令。
_asm()函数可按以下方式使用。
_asm(汇编语言字符串)
在汇编语言字符串中,可以通过回车和换行符把各个语句分开。
在C语言中使用汇编语言,可以操作C语言中的全局变量或完成用C语言难于完成的功能,但要注意以下几点:
①#asm不允许嵌套使用。
②当使用asm语句时,编译系统并不输出目标模块,而只输出汇编源文件。
③ _asm只能用小写字母,如果写成大写,就作为普通变量。
④#asm#endasm和_asm只能用在函数内。
c语言预编译条件指令
c语言预编译条件指令
C语言中的预编译条件指令是用来在编译过程中根据不同的条
件选择性地包含或排除代码的一种机制。
预编译条件指令以`#`开头,常用的预编译条件指令有以下几种:
1. `#ifdef`和`#ifndef`,用于条件编译,根据某个宏是否已
经定义来选择性地编译代码块。
`#ifdef`表示如果某个宏已经定义,则编译下面的代码块,否则跳过;`#ifndef`则表示如果某个宏未定义,则编译下面的代码块,否则跳过。
2. `#if`、`#elif`和`#else`,用于条件编译,根据给定的表
达式结果来选择性地编译代码块。
`#if`后面跟着一个表达式,如果
表达式结果为真(非零),则编译下面的代码块;`#elif`用于指定
第二个条件,如果前面的条件不满足且该条件满足,则编译下面的
代码块;`#else`用于指定以上条件都不满足时要编译的代码块。
3. `#endif`,用于结束条件编译块。
4. `#define`,用于定义宏,可以在代码中使用宏来代替一些
常量或者代码片段,提高代码的可读性和维护性。
5. `#undef`,用于取消已定义的宏。
6. `#include`,用于包含头文件,将头文件中的内容插入到当前位置。
通过使用这些预编译条件指令,我们可以根据不同的条件在编译过程中选择性地包含或排除特定的代码,从而实现更灵活、可配置的代码编译。
这在处理不同平台、不同需求或者不同版本的代码时非常有用。
C51几个预编译指令的用法
C51几个预编译指令的用法标签:指令用法编译2009-07-31 10:47预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。
可见预处理过程先于编译器对源代码进行处理。
在C语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。
要完成这些工作,就需要使用预处理程序。
尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。
预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。
预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。
#号必须是该行除了任何空白字符外的第一个字符。
#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。
整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
下面是部分预处理指令:指令用途#空指令,无任何效果#include包含一个源代码文件#define定义宏#undef取消已定义的宏#if如果给定条件为真,则编译下面代码#ifdef如果宏已经定义,则编译下面代码#ifndef如果宏没有定义,则编译下面代码#elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码#endif结束一个#if……#else条件编译块#error停止编译并显示错误信息一、文件包含#include预处理指令的作用是在指令处展开被包含的文件。
包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。
标准C编译器至少支持八重嵌套包含。
预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。
这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。
例如:#define AAA#include "t.c"#undef AAA#include "t.c"为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。
C51编译器中的预处理器指令及使用解析
C51编译器中的预处理器指令及使用解析Cx51编译器中的预处理器处理源程序文件中的指令。
Cx51支持所有的ANSI C指令。
Directives指令预处理器指令前面不能有空格,并且必须加前缀‘#’如:#pragma#include#define DEBUG 1下面列出预处理器指信令和简单描述指令描述Define 定义一个预处理器宏或常量elif 如果前面的if,ifdef,ifndef或elif分支都不成立的话,初始化if条件的一个分支else 如果前面的if,ifdef或ifndef分支都不成立的话,初始化if条件的一个分支endif 结束一个if,ifdef,ifndef,elif,或else 块error 输出用户定义的一个错误信息。
这个指令使用编译器发出一个特定的错误信息ifdef 为条件编译求表达式的值。
要被计算的参数就是一个definiTIon 定义的名字ifndef 与ifdef相同,只是如果这个名字没有被定义时运算结果为真if 为条件编译求表达式的值include 从外部文件中读取源程序文本。
line 指定一个行号和一个可选的文件名,这个指令用于在错误信息中定位错误的位置。
Specifies a line number together with an opTIonal filename. These specificaTIons are used in error messages to idenTIfy the error position.pragma 允许你使用可以在C51命令行上使用的控制指令。
Allows you to specify control directives that may be included on the C51 command line. Pragmas may contain the same control directives that are specified on the command line.undef 检查一个宏或常量是否已经定义Stringize Operator(#)字符化操作符#如果操作符出现在宏的参数的前面,参数库就会做为字符串传递到宏里。
keil c51详细使用
一、Keil C51开发系统基本知识1、Keil C51单片机软件开发系统的整体结构C51工具包的整体结构,如图1所示,其中uVision与Ishell分别是C51 for Windows和for Dos的集成开发环境(IDE),可以完成编辑、编译、连接、调试、仿真等整个开发流程。
开发人员可用IDE本身或其它编辑器编辑C或汇编源文件。
然后分别由C51及A51编译器编译生成目标文件(.OBJ)。
目标文件可由LIB51创建生成库文件,也可以与库文件一起经L51连接定位生成绝对目标文件(.ABS)。
ABS文件由OH51转换成标准的Hex文件,以供调试器dScope51或tScope51使用进行源代码级调试,也可由仿真器使用直接对目标板进行调试,也可以直接写入程序存贮器如EPROM中。
图 1 C51工具包整体结构图2、Keil C51工具包的安装1)C51 for Dos在Windows下直接运行软件包中DOS\C51DOS.exe然后选择安装目录即可。
完毕后欲使系统正常工作须进行以下操作(设C:\C51为安装目录):修改Autoexec.bat,加入path=C:\C51\BinSet C51LIB=C:\C51\LIBSet C51INC=C:\C51\INC然后运行Autoexec.bat2)C51 for Windows的安装及注意事项在Windows下运行软件包中WIN\Setup.exe,最好选择安装目录与C51 for Dos相同,这样设置最简单(设安装于C:\C51目录下)。
然后将软件包中crack目录中的文件拷入C:\C51\Bin 目录下。
3、Keil C51工具包各部分功能及使用简介1)C51与A51A.C51C51是C语言编译器,其使用方法为:C51 sourcefile[编译控制指令]或者 C51 @ commandfile其中sourcefile为C源文件(.C)。
大量的编译控制指令完成C51编译器的全部功能。
预处理命令
3
math.h——文件包含数学程序。 reg51.h——文件中包含51单片机的特殊寄存器定义。 reg52.h——文件中包含52单片机的特殊寄存器定义。 setjmp.h——文件包含定义jmp_buf类型和setjmp和longjmp程序原型。 stdarg.h——文件包含可变长度参数列表程序。 stdlib.h——文件包含存储区分配程序。 stdio.h——文件包含标准输入和输出程序。 string.h——文件包含字符串操作程序、缓冲区操作程序。 对于51单片机而言,源程序开头必须要包含reg51.h头文件,因为该文件对51单片 机的相关位及寄存器进行了定义,这样在程序中才可以正常使用寄存器等资源。
#else 程序段2
#endif 若常量表达式成立,则编译程序1,否则编译程序2。
5
单片机原理及应用
单片机原理及应用
C51语言中提供了各种预处理命令,其作用类似于汇编程序中的伪指令。在编译环 境对源程序进行编译前,需要先对程序中的预处理命令进行处理,然后将处理结果和源 程序一起编译。C51语言中的预处理命令包括宏定义命令、文件包含命令和条件编译命 令等。通常,除条件编译命令外,预处理命令一般放在函数体之外,并且通常都放置在 源文件的开头。
句如下:
outputs=0xff;
/*输出 1111 1111 */
进行编译时,预处理器会将整个程序中的所有outputs替换为P2。
2.文件包含命令
#include命令的功能是将指定的定义或声明文件放入程序之中,该命令常用于引入 标准库函数文件。下面是一些常用的C51头文件:
absacc.h——包含允许直接访问8051不同存储区的宏定义。 assert.h——文件定义宏,用来建立程序的测试条件。 ctype.h——包含字符转换和分类程序。 intrins.h——文件包含指示编译器产生嵌入式固有代码的程序原型。
KeilC51编译器的控制指令1
第一节 Keil C51编译器的控制指令C51编译器的控制指令分为三类:源文件控制类,目标文件控制类及列表控制类。
1. 源文件控制类NOEXTEND:C51源文件不允许使用ANSI C扩展功能。
DEFINE(DF):定义预处理(在C51命令行)。
2. 目标文件(Object)控制类:COMPACT LARGE SMALL 选编译模式DEBUG(DB) 包含调试信息,以供仿真器或dSCope51使用。
NOAMAKE(NOAM) 禁止AutoMake信息记录NOREGPARMS 禁止用寄存器传递参数OBJECTEXTEND(OE) Object文件包含附加变量类型信息OPTIMIZE(OT) 指定优化级别REGFILE(RF) 指定一个寄存器使用的文件以供整体优化用REGISTERBANK(RB) 指定一个供绝对寄存器访问的寄存器区名SRC 不生成目标文件只生成汇编源文件其它控件不常用。
3. 列表文件(listing)控制类:CODE(CD):向列表文件加入汇编列表LISTINCLUDE(LC):显示indude文件SYMBOLS(SB):列表文件包括模块内所有符号的列表WARNINGLEVEL(WL):选择“警告”级别第二节 dScope51的使用1. dScope51 for Dos总的来说dScope51具有以下特性:●高级语言显示模式●集成硬件环境模拟●单步或“GO”执行模式●存储器、寄存器及变量访问●Watch表达式之值●函数与信号功能下面,具体说明在进入dScope51 for Dos之后,如何实现上述功能,dScope51采用下拉菜单格式和窗口显示控制,共有language、serial、exe、register四个窗口,其中exe为命令行窗口,language为程序窗口,serial为串口窗,register为寄存器窗。
(1) 高级语言显示模式单击主菜单中的“View”,第一栏中的三条命令“Highlevel”、“Mixed”、“Assembly”分别对所装入的程序按照“高级”、“混合级”及“汇编级”三种方式显示,以方便调试使用。
c51汇编语言指令集
资料转移指令MOV 移动MOVC 程式记忆体移动MOVX 外部RAM和扩展I/O口与累加器A的数据传送指令PUSH 放入堆叠POP 由堆叠取回XCH 8位元交换XCHD 低4位元交换SWAP 高低4位元交换算术指令ADD 两数相加ADDC 两数相加再加CSUBB 两数相减再减CINC 加一指令DEC 减一指令MUL (MUL AB乘法指令仅此一条)相乘指令,所得的16位二进制数低8位存累加器A高8位存BDIV (DIV AB 除法指令仅此一条)相除指令,所得商存A,余数存BDA (DA A 只此一条指令)调整为十进数逻辑指令ANL做AND(逻辑与)运算ORL做OR(逻辑或)运算XRL 做(逻辑异或)运算CLR 清除为0CPL 取反指令RL 不带进位左环移RLC 带进位左环移RR 不带进位右环移RRC 带进位右环移控制转移类指令JC C=1时跳JNC C=0时跳JB 位元=1时跳JNB 位元=0时跳JBC 位元=1时跳且清除此位元LCALL 长调用子程序ACALL 绝对调用子程序RET 由副程式返回RETI 由中断副程式返回AJMP 绝对转移SJMP 相对转移JMP @A+DPTR 散转,相对DPTR的间接转移JZ A=0时跳JNZA 0时跳CJNE 二数比较,不相等时跳DJNZ 减一,不等於0时跳NOP 空操作位变量指令SETB 设定为1ORG 程序开始,规定程序的起始地址END 程序结束EQU 等值指令(先赋值后使用)例:SUM EQU 30HDB 定义字节指令DW 定义字内容DS 定义保留一定的存贮单元数目BIT 位地址符号指令例:SAM BIT P1.0 RET 子程序返回指令RETI 中断子程序返回指令$ 本条指令地址算术运算指令指令说明周期ADD A,Rn A←A+Rn 12ADD A,direct A←A+direct 12ADD A,@Ri A←A+Ri 12ADD A,#data A←A+data 12ADDC A,Rn A←A+Rn+C 12ADDC A,direct A←A+direct+C 12 ADDC A,@Ri A←A+Ri+C 12ADDC A,#data A←A+data+C 12SU BB A,Rn A←A-Rn-C 12SUBB A,direct A←A-direct-C 12 SUBB A,@Ri A←A-Ri-C 12SUBB A,#data A←A-data-C 12INC A A←A+1 12INC Rn Rn←Rn+1 12INC direct direct←direct+1 12INC @Ri @Ri←@Ri+1 12INC DPTR DPTR←DPTR+1 12DEC A A←A-1 12DEC Rn Rn←Rn-1 12DEC direct direct←direct-1 12DEC @Ri @Ri←@Ri-1 12MUL AB 两个无符号的8位数据相乘,其中高阶8位放入B缓存器,低阶8位则放入累积器ACC 24DIV AB 两个无符号的8位数据相除,把ACC 值除以B缓存器值,商数放回ACC,余数放在B 48DA A 累加器作十进制调整 48逻辑运算指令指令说明周期ANL A,Rn A←A and Rn 12ANL A,direct A←A and direct 12ANL A,@Ri A←A and Ri 12ANL A,#data A←A and data 12ANL direct,A direct←direct and A 12 ANL direct,#data direct←direct and data 24ORL A,Rn A←A or Rn 12ORL A,direct A←A or direct 12ORL A,Rn A←A or Rn 12ORL A,@Ri A←A or Ri 12ORL A,#data A←A or data 12ORL direct,A direct←direct or A 12 ORL direct,#data direct←direct or data 24XRL A,Rn A←A xor Rn 12XRL A,direct A←A xor direct 12XRL A,@Ri A←A xor Ri 12XRL A,#data A←A xor data 12XRL direct,A direct←direct xor A 12 XRL direct,#data dir ect←direct xor data 12CLR A 清除累加器 12CPL A 累加器反相 12RL A 累加器向左旋转 12RLC A 累加器和C左旋 12RR A 累加器向右旋转 12RRC A 累加器和C右旋 12SWAP A 累加器的高低四位互换 12数据转移指令指令说明周期MOV A,Rn A←Rn 12MOV A,direct A←direct 12MOV A,@Ri A←Ri 12MOV A,#data A←data 12MOV Rn,A Rn←A 12MOV Rn,direct Rn←direct 24MOV Rn,#data Rn←data 12MOV direct,A direct←A 12MOV direct,Rn direct←Rn 24MOV direct,direct direct←direct 24 MOV direct,@Ri direct←Ri 24MOV direct,#data direct←data 24MOV @Ri,A Ri←A 12MOV @Ri,direct Ri←direct 24MOV @Ri,#data Ri←data 12MOV DPTR,#data 16 Ri←16bit data 24 MOVC A,@A+DPTR A←程序内存的数据 24 MOVC A,@A+PC A←程序内存的数据 24 MOVX A,@Ri A←外部RAM的数据(8bit地址) 24MOVX A,@DPTR A←外部RAM的数据(16bit地址) 24MOVX @Ri,A 外部的RAM(8bit)←A 24 MOVX @DPTR,A 外部的RAM(16bit)←A 24 PUSH direc 推迭区←direct 24POP direc direct←堆栈区 24XCH A,Rn A和Rn互换 12XCH A,direct A和direct互换 12XCH A,@Ri A和Ri互换 12XCHD A,@Ri A和Ri的低四位互换 12位运算指令指令说明周期CLR C 清除进位旗标 12CLR bit 清除直接位 12SETB C 设定进位旗标 12SETB bit 设定直接位 12CPL C 进位旗标反相 12CPL bit 直接位反相 12ANL C,bit C←C and bit 24ANL C,/bit C←C and bit(反相) 24 ORL C,bit C←C or bit 24ORL C,/bit C←C or bit(反相) 24 MOV C,bit C←bit 12MOV bit,C bit←C 24JC rel 若C=1跳至rel 24JNC rel 若C=0跳至rel 24JB bit,rel 若bit=1跳至rel 24JNB bit,rel 若bit=0跳至rel 24JBC bit,rel 若bit=1跳至rel,且清除此位24程序跳跃指令指令说明周期ACALL addr11 绝对式子程序呼叫 24 LCALL addr16 远程子程序呼叫 24RET 从子程序返回 24RETI 从中断子程序返回 24AJMP addr11 绝对式跳跃 24LJMP addr16 远程跳跃 24SJMP rel 短程跳跃 24JMP @A+DPTR 间接跳跃 24JZ rel 若A=0跳至rel 24JNZ rel 若A不等于0跳至rel 24CJNE A,direct,rel 若A不等于direct跳至rel 24CJNE A,#data,rel 若A不等于data跳至rel 24CJNE Rn,#data,rel 若Rn不等于data跳至rel 24CJNE @Ri,#data,rel 若Ri不等于data跳至rel 24DJNZ Rn,rel Rn减1不等于0跳至rel 24 DJNZ direct,rel direct减1不等于0跳至rel 24NOP 没动作 12缩写符号说明缩写符号说明备注Rn 缓存器R0-R7direct 8bit内部数据存储器,包括1.内部数据存储器(00-7F)的地址2.特殊功能缓存器(80-FF)的地址,如P0,PSW,TMOD..等@Ri 由缓存器R0或R1所寻址的内部RAM数据#data 8bit常数#data 16 16bit常数addr 16 16bit的目的地址,可使跳跃指令跳跃64kaddr 11 11bit的目的地址,可使跳跃指令跳跃2krel 具正负号的8位地址偏移量,用于相对地址的跳跃bit 1个bit:只所有可以位寻址的位。
C51编译指令
预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。
可见预处理过程先于编译器对源代码进行处理。
在C语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。
要完成这些工作,就需要使用预处理程序。
尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。
预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。
预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。
#号必须是该行除了任何空白字符外的第一个字符。
#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。
整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
下面是部分预处理指令:指令用途# 空指令,无任何效果#include 包含一个源代码文件#define 定义宏#undef 取消已定义的宏#if 如果给定条件为真,则编译下面代码#ifdef 如果宏已经定义,则编译下面代码#ifndef 如果宏没有定义,则编译下面代码#elif 如果前面的#if给定条件不为真,当前条件为真,则编译下面代码#endif 结束一个#if……#else条件编译块#error 停止编译并显示错误信息一、文件包含#include预处理指令的作用是在指令处展开被包含的文件。
包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。
标准C编译器至少支持八重嵌套包含。
预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。
这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。
例如:#define AAA#include "t.c"#undef AAA#include "t.c"为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。
C51的预处理命令
8.3.1 #define命令
• #define命令用于定义一个宏名。宏名是一个标识 符,在源代码中遇到该标识符时,均以宏定义的 串的内容代替该标识符。ANSI标准宏将定义的标 识符称为“宏名”,而用定义的内容代替宏名的 过程称为“宏替换”。#define命令用于定义宏名 时,既可以带参数,也可以不带参数,下面分别 介绍这两种情况。
//引用自定义文件myfile • #include <studio.h>
//引用库函数文件studio • #include <reg51.h>
//引用寄存器文件 • define MATH_FILE "C\keil\inc\math1.h"
//宏定义自定义文件MATH_FILE • #include MATH_FILE
• 1.不带参数的宏定义 • 2.带参数的宏定义
8.3.2 #undef命令
• #undef命令用于取消前面用#define命令定义过的宏名。一般形式为:
• #undef 宏名
• ቤተ መጻሕፍቲ ባይዱ中,“#undef”是取消宏定义指令,“宏名”为前面用#define命令定义过的标识 符。
• 使用#undef命令的目的是将宏名局限在指定的代码段中,这样可以限制宏定义的使用 范围。使用#undef命令的程序示例如下:
8.3 宏定义指令
• 宏定义指令是指用一些标识符作为宏名,来代替 其他一些符号或者常量的预处理命令。使用宏定 义指令,可以减少程序中字符串输入的工作量, 而且可以提高程序的可移植性。
• 宏名既可以是字符串或常数,也可以是带参数的 宏。宏定义指令可分为带参数的宏定义和不带参 数的宏定义。下面分别介绍用于宏定义的一些预 处理命令。
C51几个预编译指令的用法
C51几个预编译指令的用法标签:指令用法编译2009-07-31 10:47预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。
可见预处理过程先于编译器对源代码进行处理。
在C语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。
要完成这些工作,就需要使用预处理程序。
尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。
预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。
预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。
#号必须是该行除了任何空白字符外的第一个字符。
#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。
整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
下面是部分预处理指令:指令用途#空指令,无任何效果#include包含一个源代码文件#define定义宏#undef取消已定义的宏#if如果给定条件为真,则编译下面代码#ifdef如果宏已经定义,则编译下面代码#ifndef如果宏没有定义,则编译下面代码#elif如果前面的#if给定条件不为真,当前条件为真,则编译下面代码#endif结束一个#if……#else条件编译块#error停止编译并显示错误信息一、文件包含#include预处理指令的作用是在指令处展开被包含的文件。
包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。
标准C编译器至少支持八重嵌套包含。
预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。
这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。
例如:#define AAA#include "t.c"#undef AAA#include "t.c"为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。
C51指令表
)→))C51汇编伪指令:1、DS ---预留存储区命令格式:〔标号:〕DS 表达式值其功能是从指定地址开始,定义一个存储区,以备源程序使用。
存储区预留的存储单元数由表达式的值决定。
TMP: DS 1从标号TEP地址处开始保留1个存储单元(字节)。
2、BIT---定义位命令格式:字符名称BIT 位地址其功能用于给字符名称定义位地址。
SPK BIT P3.7经定义后,允许在指令中用SPK代替P3.7。
3、USING指令USING指令通知汇编器使用8051的哪一个工作寄存器组。
格式:USING 表达式(值必须为0-3,默认值为0。
)USING 0使用第0组工作寄存器。
4、SEGMENT指令SEGMENT 指令用来声明一个再定位段和一个可选的再定位类型。
格式:再定位段名SEGMENT 段类型〔再定位类型〕其中,“再定位段名”用于指明所声明的段。
“段类型”用于指定所声明的段将处的存储器地址空间。
可用的段类型有CODE、XDA TA、DA TA、IDA TA和BIT。
STACK_SEG SEGMENT IDA TADA TA_SEG SEGMENT DATA5、RSEG---再定位段选择指令再定位段选择指令为RSEG,用于选择一个已在前面定义过的再定位段作为当前段。
格式:RSEG 段名段名必须是在前面已经声明过的再定位段。
DA TA_SEG SEGMENT DATA ;声明一个再定位DA TA段RSEG DATA_SEG ;选择前面声明的再定位DA TA段作为当前段6、绝对段选择指令CSEG---绝对代码段DSEG---内部绝对数据段XSEG---外部绝对数据段ISEG---内部间接寻址数据段BSEG---绝对位寻址数据段格式:CSEG [AT 绝对地址表达式]DSEG [AT 绝对地址表达式]XSEG [AT 绝对地址表达式]ISEG [AT 绝对地址表达式]BSEG [AT 绝对地址表达式]括号内是可选项,用来指定当前绝对段的基地址。
【精品】keil预处理命令及方法
14.4.2 #elif命令
• #elif 命令用于进行多种编译选择。其意义与“ else if” 相同,形成一个 if-else-if 阶梯状语句。此时条件编译的 一般形式如下: • #if 表达式0 • 语句段; • #elif 表达式1 • 语句段; • #elif 表达式2 • 语句段; • #elif 表达式3 • 语句段; • … • #elif 表达式n • 语句段; • #endif
14.4 条件编译指令
• 条件编译指令用于对程序源代码的各部分有选择 地进行编译。采用条件汇编,可以提高程序的适 用性,缩小目标代码的大小。 • 在默认情况下,源程序中的所有行都要进行编译。 但是有时需要某些语句行在条件满足的情况下, 才进行编译,此时便用到条件编译指令。目前商 业软件公司广泛应用条件编译来制作某个程序的 许多不同用户版本。
•
• • • • • • •
14.2 宏定义指令
• 宏定义指令是用一些标识符作为宏名来代替一些 符号或者常量的命令。宏定义指令可以带参数, 也可以不带参数。下面分别介绍用于宏定义的一 些预处理指令。
14.2.1 #define命令
• #define命令用于定义一个“宏名”。其中“宏名”是一个 标识符,在源程序中遇到该标识符时,均以定义的串的内 容替代该标识符。 ANSI 标准将标识符定义为“宏名”,这 个替换过程称为“宏替换”。#define命令用于定义宏名时, 可以带参数,也可以不带参数,下面分别介绍这两种情况。 • 1.不带参数的宏定义 • 不带参数的宏定义,其一般形式如下: • #define 标识符 字符串 • 其中,#define是宏定义指令,标识符即宏名,字符串是被 替换的对象。典型的宏定义指令示例如下: • #define TURE 1 • #define FALSE 0 • #define PI 3.1415926 • 2.带参数的宏定义 • 带参数的宏定义指令,其一般形式如下: • #define 宏名(参数表) 字符串
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C51几个预编译指令的用法标签:指令用法编译2009-07-31 10:47预处理过程扫描源代码,对其进行初步的转换,产生新的源代码提供给编译器。
可见预处理过程先于编译器对源代码进行处理。
在C 语言中,并没有任何内在的机制来完成如下一些功能:在编译时包含其他源文件、定义宏、根据条件决定编译时是否包含某些代码。
要完成这些工作,就需要使用预处理程序。
尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。
预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行响应的转换。
预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。
#号必须是该行除了任何空白字符外的第一个字符。
#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。
整行语句构成了一条预处理指令,该指令将在编译器进行编译之前对源代码做某些转换。
下面是部分预处理指令:指令用途#空指令,无任何效果#include 包含一个源代码文件#define 定义宏#undef 取消已定义的宏#if 如果给定条件为真,则编译下面代码#ifdef 如果宏已经定义,则编译下面代码#ifndef 如果宏没有定义,则编译下面代码#elif 如果前面的#if 给定条件不为真,当前条件为真,则编译下面代码#en dif结束一个#if ......... #e条件编译块#error 停止编译并显示错误信息一、文件包含#include 预处理指令的作用是在指令处展开被包含的文件。
包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。
标准C编译器至少支持八重嵌套包含。
预处理过程不检查在转换单元中是否已经包含了某个文件并阻止对它的多次包含。
这样就可以在多次包含同一个头文件时,通过给定编译时的条件来达到不同的效果。
例如:#define AAA#include "t.c"#undef AAA#include "t.c"为了避免那些只能包含一次的头文件被多次包含,可以在头文件中用编译时条件来进行控制。
例如:#ifndef MY_H#define MY_H#endif在程序中包含头文件有两种格式:#include <my.h>#include "my.h"第一种方法是用尖括号把头文件括起来。
这种格式告诉预处理程序在编译器自带的或外部库的头文件中搜索被包含的头文件。
第二种方法是用双引号把头文件括起来。
这种格式告诉预处理程序在当前被编译的应用程序的源代码文件中搜索被包含的头文件,如果找不到,再搜索编译器自带的头文件。
采用两种不同包含格式的理由在于,编译器是安装在公共子目录下的,而被编译的应用程序是在它们自己的私有子目录下的。
一个应用程序既包含编译器提供的公共头文件,也包含自定义的私有头文件。
采用两种不同的包含格式使得编译器能够在很多头文件中区别出一组公共的头文件。
二、宏宏定义了一个代表特定内容的标识符。
预处理过程会把源代码中出现的宏标识符替换成宏定义时的值。
宏最常见的用法是定义代表某个值的全局符号。
宏的第二种用法是定义带参数的宏,这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。
1. #define 指令#define 预处理指令是用来定义宏的。
该指令最简单的格式是:首先神明一个标识符,然后给出这个标识符代表的代码。
在后面的源代码中,就用这些代码来替代该标识符。
这种宏把程序中要用到的一些全局值提取出来,赋给一些记忆标识符。
#define MAX_NUM 10int array[MAX_NUM];for(i=0;i<MAX_NUM;i++)在这个例子中,对于阅读该程序的人来说,符号MAX_NUM 就有特定的含义,它代表的值给出了数组所能容纳的最大元素数目。
程序中可以多次使用这个值。
作为一种约定,习惯上总是全部用大写字母来定义宏,这样易于把程序红的宏标识符和一般变量标识符区别开来。
如果想要改变数组的大小,只需要更改宏定义并重新编译程序即可。
宏表示的值可以是一个常量表达式,其中允许包括前面已经定义的宏标识符。
例如:#define ONE 1#define TWO 2#define THREE (ONE+TWO) 注意上面的宏定义使用了括号。
尽管它们并不是必须的。
但出于谨慎考虑,还是应该加上括号的。
例如:six=THREE*TWO;预处理过程把上面的一行代码转换成:six=(ONE+TWO)*TWO;如果没有那个括号,就转换成six=ONE+TWO*TWOT。
xx 还可以代表一个字符串常量,例如:#define VERSION "Version1.0 Copyright(c) 2003"2. 带参数的#define 指令带参数的宏和函数调用看起来有些相似。
看一个例子:#define Cube(x) (x)*(x)*(x)可以时任何数字表达式甚至函数调用来代替参数X。
这里再次提醒大家注意括号的使用。
宏展开后完全包含在一对括号中,而且参数也包含在括号中,这样就保证了宏和参数的完整性。
看一个用法:int num=8+2;volume=Cube(num);展开后为(8+2)*(8+2)*(8+2);如果没有那些括号就变为8+2*8+2*8+2 了。
下面的用法是不安全的:volume=Cube(num++);如果Cube是一个函数,上面的写法是可以理解的。
但是,因为Cube是个宏,所以会产生副作用。
这里的擦书不是简单的表达式,它们将产生意想不到的结果。
它们展开后是这样的:volume=(num++)*(num++)*(num++);很显然,结果是10*11*12, 而不是10*10*10;那么怎样安全的使用Cube宏呢?必须把可能产生副作用的操作移到宏调用的外面进行:int num=8+2;volume=Cube(num);num++;3. #运算符出现在宏定义中的#运算符把跟在其后的参数转换成一个字符串。
有时把这种用法的#称为字符串化运算符。
例如:#define PASTE(n) "adhfkj"#nmain(){printf("%s\n",PASTE(15));}宏定义中的#运算符告诉预处理程序,把源代码中任何传递给该宏的参数转换成一个字符串。
所以输出应该是adhfkj15。
4. ##运算符##运算符用于把参数连接到一起。
预处理程序把出现在##两侧的参数合并成一个符号。
看下面的例子:#define NUM(a,b,c) a##b##c#define STR(a,b,c) a##b##c main()printf("%d\n",NUM(1,2,3));printf("%s\n",STR("aa","bb","cc"));} 最后程序的输出为:123 aabbcc 千万别担心,除非需要或者宏的用法恰好和手头的工作相关,否则很少有程序员会知道##运算符。
绝大多数程序员从来没用过它。
三、条件编译指令条件编译指令将决定那些代码被编译,而哪些是不被编译的。
可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件。
1. #if 指令#if 指令检测跟在制造另关键字后的常量表达式。
如果表达式为真,则编译后面的代码,知道出现#else、#elif 或#endif 为止;否则就不编译。
2. #endif 指令#endif 用于终止#if 预处理指令。
#define DEBUG 0 main(){#if DEBUG printf("Debugging\n");#endifprintf("Running\n");}由于程序定义DEBUG宏代表0,所以#if条件为假,不编译后面的代码直到#endif,所以程序直接输出Running。
3. #ifdef 和#ifndef#define DEBUGmain(){#ifdef DEBUGprintf("yes\n");#endif#ifndef DEBUGprintf("no\n");#endif}#if defined 等价于#ifdef; #if !defined 等价于#ifndef4. #else 指令#else指令用于某个#if指令之后,当前面的#if指令的条件不为真时,就编译#else后面的代码。
#endif指令将中指上面的条件块。
#define DEBUGmain(){#ifdef DEBUGprintf("Debugging\n");#elseprintf("Not debugging\n");#endifprintf("Running\n");}5. #elif 指令#elif预处理指令综合了#else和#if指令的作用。
#define TWOmain(){#ifdef ONE printf("1\n");#elif defined TWOprintf("2\n");#elseprintf("3\n");#en dif}程序很好理解,最后输出结果是2。
6. 其他一些标准指令#error 指令将使编译器显示一条错误信息,然后停止编译。
#line 指令可以改变编译器用来指出警告和错误信息的文件号和行号。
#pragma指令没有正式的定义。
编译器可以自定义其用途。
典型的用法是禁止或允许某些烦人的警告信息。