汇编语言与C的混合编程PPT教学课件

合集下载

第四讲 ARM汇编语言及嵌入式C混合编程ppt课件

第四讲 ARM汇编语言及嵌入式C混合编程ppt课件
十六进制数前要使用前缀0x,不能使用&。 当使用8位移位常量导致CPSR中的ALU标志 位需要更新时,N、Z、C、V标志中的C不具 有实际意义
TM
23
内嵌汇编器与armasm汇编器的区别
指令中使用的C变量不能与任何物理寄存器同名, 否则会造成混乱
不支持BX和BLX指令 使用内嵌汇编器,不能通过对程序计数器PC赋值,
(4)通用寄存器R13用作数据栈指针,记作 SP。
TM
5
(5)通用寄存器R14用作链接寄存器 ;
(6)通用寄存器R15用作程序计数器,记作 PC 。
TM
6
8.5.2数据栈使用规则
过程调用标准规定数据栈为FD类型,并且对 数据栈的操作时要求8字节对齐的。
TM
7
8.5.3参数传递规则
1.参数个数可变的子程序参数传递规则 对于参数个数可变的子程序,当参数个数不
超过4个时,可以使用寄存器R0~R3来传递; 当参数个数超过4个时,还可以使用数据栈进 行参数传递。
TM
8
2.参数个数固定的子程序参数传递规则
如果系统不包含浮点运算的硬件部件且没有浮点参 数时,则依次将各参数传送到寄存器R0~R3中, 如果参数个数多于4个,将剩余的字数据通过数据 栈来传递;
如果包括浮点参数则要通过相应的规则将浮点参数 转换为整数参数,然后依次将各参数传送到寄存器 R0~R3中。如果参数多于4个,将剩余字数据传送 到数据栈中,入栈的顺序与参数顺序相反,即最后 一个字数据先入栈。
TM
35
每一步:建立启动C程序的代码,请读者参阅前面 的章节自行建立。
每二步:建立C语言源文件main.c
TM
36
每三步:建立汇编源文件Factorial.s

汇编语言与C的混合编程

汇编语言与C的混合编程

1.3常量
• 在内嵌的汇编指令中,常量前的符号#可以省略。如果在一个表达式 前使用#,则该表达式必须是一个#。 • 1.4指令展开 • 内嵌的汇编指令中如果包含常量操作数,则该指令可能会被汇编器展 开成几条指令。例如指令: • ADD R0,R0,#1023 • 可能会被展开成下面的指令序列 • ADD R0,R0,#1024 • SUB R0,R0,#01 • 乘法指令MUL可能会被展开成一系列的加法操作和移位操作。 • 事实上,除了与协处理器相关的指令外,大部分的ARM指令和 Thumb指令中包含常量操作数都可能被展开成多条指令。
1.2物理寄存器
• 在内嵌的汇编指令中使用物理寄存器有一下限制: • 不能直接向PC寄存器中赋值,程序的跳转只能通过B指令和BL指令实 现。 • 在使用物理寄存器的内嵌汇编指令中,不要使用过于复杂的C表达式, 因为当表达式过于复杂时,将会需要较多的物理寄存器,这些寄存器 可能与指令中的物理寄存器的使用冲突。 • 编译器可能会使用R1寄存器或者R13寄存器存放编译的中间结果,在 计算表达式值时可能会将寄存器R0~R3、R2以及R14用于子程序的调 用。因此在内嵌的汇编指令中,不要将这些寄存器同时指定为指令中 的物理寄存器。 • 在内嵌的汇编指令中使用物理寄存器时,如果有C变量使用了该物理 寄存器,编译器将在合适的时候保存并恢复该变量的值。需要注意的 是,当寄存器sp、sl、fp以及sb用做特定的用途时,编译器不能恢复 这些寄存器的值。 • 通常推荐在内嵌的汇编指令中不要指定物理寄存器,因为这可能会影 响编译器分配寄存器,进而可能影响代码的效率。
• 下面是一个在汇编程序中访问C程序全局变量的例子。程序中变量 globv1是在C程序中声明的全局变量。在汇编程序中首先使用 IMPORT伪操作声明该变量;R0中;修改后再将寄存器R0的值赋予变量 globv1.本例中程序如下: • AREA globals,CODE,READONLY • EXPORT asmsub • IMPORT global ;用IMPORT伪指令声明该变量 • asmsum • LDR R1,# globv1 ;将其内存地址读入到寄存器R1中 • LDR R0,[R1] ;再将其值读入到寄存器R0中 • ADD R0,R0,#2 • STR R0,[R1] ;修改后再将寄存器R0的值赋予变量globv1 • MOV PC,LR • END

第8章+汇编语言与C的混合编程

第8章+汇编语言与C的混合编程
82turboc模块连接方式821混合编程的约定规则1命名约定c编译器对c源程序编译时要将其中的变量名过程名函数名等标识符前加下划线而汇编程序在汇编时直接使用所以被c语言调用的汇编程序的所有标识符前都要加下划线以保持两者标识符一致
第八章
汇编语言与C的混合编程
LOGO
本章要点
混合编程是指使用两种或两种以上的程序设计 语言,通过相互调用、参数传递、共享数据结 构和数据信息而形成程序的过程。采用高级语 言与汇编语言混合编程,从而充分利用各种程 序设计语言各自的优势,即程序的大部分采用 高级语言编写,以提高程序的开发效率;在某 些部分利用汇编语言编写,以提高程序的运行 效率。 Turbo C嵌入汇编方式 Turbo C模块连接方式 汇编语言在Visual C++中的应用
2)返回值的传递 被调用函数的返回值,按下列规则传递给调用 者:如果返回值小于或等于16位,则将其存放在AX 寄存器中;如果返回值是32位,则存放在DX.AX寄 存器对中,其中,DX存储高16位,AX存储低16位; 如果返回值大于32位,则存放在静态变量存储区, AX寄存器存放指向这个存储区的偏移地址;对于32 位far指针,则还利用DX存放段地址。 由此可见,汇编语言子程序向C程序返回处理 结果时,是通过AX和DX完成的。但对于不同长度 的返回数据,使用寄存器的情况也不同。
3)地址参数的传递 C语言程序的参数传递,可采用传数值和传地址两种 方式。如果参数是传值的,可直接写出实际参数;如果 参数是传址的,则在说明中将参数类型说明为指针类型, 调用时,用“&”取得变量的地址作为实参传递。 在汇编语言子程序中,利用基址指针BP,先取得地 址,再间接取内容,修改后送回原处,同时以RET返回。 以传址方式传送参数时,实际被压入堆栈的是参数 所在的逻辑地址。这个地址也要分为近指针(仅含偏移 地址)和远指针(含段地址和偏移地址)。C语言程序 以tiny、small、compact模式编译时,它以near近指 针传递地址,在堆栈占2字节;如果C语言程序以 medium、large、huge模式编译,则地址是32位的远 指针,在堆栈中要占4 字节。

第5章 汇编语言C语言混合编程

第5章 汇编语言C语言混合编程

• • • • • •
DCB 分配一片连续的字节存储单元并初始化。
DCW(DCWU)分配一片连续的半字存储单元并初始化。 DCD(DCDU)分配一片连续的字存储单元并初始化。 DCQ(DCQU)分配一片以8字节为单位的连续的存储单元并初始化。 DCFS(DCFSU)为单精度浮点数分配一片连续的字存储单元并初始化。
DCFD(DCFDU)为双精度浮点数分配一片连续的字存储单元并初始化。
23
5.2.1 符号定义伪操作
例 4 使用示例:
LCLA
Test3 LCLL Test4
Test3
SETA Test4 SETL
Байду номын сангаас
;声明一个局部的数值变量,变量名为Test3
0xaa ;将该变量赋值为0xaa ;声明一个局部的逻辑变量,变量名为Test4 {TRUE} ;将该变量赋值为真
5.2.1 符号定义伪操作
MOV R1, #NVIC_IRQ0_ENABLE ; 把立即数传送到R1中
(4)注释域(COMMENT)
注释域用来说明语句的功能,以“;”开始。汇编程序对“;”以
后的部分不予汇编。
例 1 指令和伪操作书写格式的举例 AREA EX4_3,CODE,READONLY ;前面必须有空格 GBLA DATA DATA SETA 0x20 ADD R0,R1,R2 ADD R0,R1,r2 add R0,R1,r2 ;前面必须有空格 ;DATA变量名前面不能留空格 ;全部大写,正确 ;寄存器小写,正确 ;指令助记符小写,寄存器大写或小写,正确
GBLA伪操作用于定义一个全局的数值变量,并初始化为0;
GBLL伪操作用于定义一个全局的逻辑变量,并初始化为F(假); GBLS伪操作用于定义一个全局的字符串变量,并初始化为空;

第7章 汇编语言与C/C++的混合编程

第7章 汇编语言与C/C++的混合编程
对于具有内嵌汇编语句的C程序,C编译器要调用汇 编程序进行汇编。
汇编程序在分析一条嵌入式汇编指令的操作数时,若 遇到了一个标识符,它将在C程序的符号表中搜索该 标识符;但8086寄存器名不在搜索范围之内,而且大 小写形式的寄存器名都可以使用。
8
访问C语言的数据
例7.1:用嵌入汇编方式实现取两数较小值的函数min
例7.3-2/2
➢利用汇编程序编译汇编语言程序成目标代码文件: ML /c lt703s.asm 或 masm lt703s.asm
➢利用C编译程序编译C程序、连接目标代码文件: TCC -c lt703.c
DEMO
编译和连接过程
利用连接程序将各个目标代码文件连接在一起,得到可 执行程序文件,例如:
例如,上例可以利用如下命令:
TCC -ms -Iinclude -Llib lt703.c lt703s.obj
16
7.2.3 混合编程的参数传递
Lt0701.c 的编译结果——如教材P218 mov ax,200 push ax ;压入参数200(第2个参数) mov ax,100 push ax ;压入参数100(第1个参数) call near ptr _min ;调用min(100,200) pop cx ;两条出栈指令用于平衡堆栈 pop cx
shl eax,cl
;计算
ret
;EAX存放返回值
power2 ENDP
end
// C++语言程序:lt714.cpp
例7.14-3/3
# include <iostream.h>
extern “c”{int power2(int,int);}
void main(void)

第6章 C语言和汇编语言混合编程(C55x DSP)

第6章  C语言和汇编语言混合编程(C55x DSP)

第6章 C语言和汇编语言混合编程
2. 编译模式 使用C编译器,在进入汇编程序时,C55x的CPL(编译模 式位)自动被置1,相对寻址模式使用堆栈指针SP。如果在汇 编程序中需要使用相对直接寻址模式访问数据存储器,则必 须改成数据页DP直接寻址模式,这可以通过清CPL位实现。 在返回C调用程序前,CPL位必须重新置1。
序清单输入到这些文件当中,保存并将其添加到工程之中。
第6章 C语言和汇编语言混合编程
3. 编译链接工程和装载输出文件 编译链接工程,修改错误,直到无错误信息提示为止, 再装载输出文件。 4. 打开CPU寄存器视窗 在主菜单中选择View→Registers→CPU Registers命令, 打开CPU寄存器视窗,观察CPU寄存器的变化情况。
int s4; s4=sum(); s1=mac1(x,a,n); //*ar0=x[0],*ar1=a[0],t0=n,return is stored in t0
s2=mac2(x,a,n);
//*ar0=x[0],*ar1=a[0],t0=n,return is stored in ac0
第6章 C语言和汇编语言混合编程
“ _ ”。以下是C函数调用汇编子程序的例子。
第6章 C语言和汇编语言混合编程
//C源程序: extern int sum(int *); //参考一个汇编函数 int x[4]={0x1223,0x345,0x2345,0x3444}; //定义全局变量并初始化
int s;
void main() {
参数类型和寄存器安排顺序表。
第6章 C语言和汇编语言混合编程
表6-1 参数类型和寄存器安排顺序表
第6章 C语言和汇编语言混合编程

第六讲_C与汇编语言混合编程

第六讲_C与汇编语言混合编程

数据栈的使用规则
•根据堆栈指针指向位置的不同 和增长方向的不同 可以分为以下4种数据栈 : FD (Full Descending) 满递减 ED (Empty Descending)空递减 FA (Full Ascending) 满递增 EA (Empty Ascending) 空递增 ATPCS规定数据栈为FD(满递减)类型,并且 对数据栈的操作是8字节对齐的。
内嵌汇编注意事项
必须小心使用物理寄存器,如R0~R3,LR和PC。 不要使用寄存器寻址变量。 使用内嵌汇编时,编译器自己会保存和恢复它可能用 到的寄存器,用户无须保存和恢复寄存器。 LDM和STM指令的寄存器列表只允许物理寄存器。 汇编语言用“,”作为操作数分隔符
三、C和ARM汇编程序间相互调用
内嵌汇编指令的语法格式
• __asm(“指令[;指令]”); • ARM C汇编器使用关键字“__asm"。如果有多 条汇编指令需要嵌入,可以用“{}”将它们 归为一条语句。如: • __asm •{ • 指令[;指令] • … • [指令] •} • 需要特别注意的是__asm是两个下划线。
内嵌的汇编指令的特点
在 C 和 ARM 汇编程序之间相互调用必须遵守 ATPCS (ARM-Thumb Procedure Call Standard)规则。 C和汇编之间的相互调用可以从以下这程序中调用C语言程序
汇编程序访问全局C变量
C函数原型: int g(int a,int b,int c,int d,int e) { return a+b+c+d+e; } ////汇编程序调用C程序g()计算5个整数i, 2*i, 3*i, 4*i, 5*i 的和。 汇编源程序: EXPORT f AREA f,CODE,READONLY IMPORT g ;声明该变量函数g( ),i在R0中 STR LR,[SP,#- 4]! ;预先保存LR ADD R1,R0,R0 ;计算2 * i(第2个参数) ADD R2,R1,R0 ;计算3*i(第3个参数) ADD R3,R1,R2 ;计算5*i(第5个参数) STR R3,[SP,#- 4]! ;将第5个参数压人堆栈 ADD R3,R1,R1 ;计算4 * i(第4个参数) BL g ;调用C程序g( ) ADD SP,SP,#4 ;调整数据栈指针,准备返回 LDR PC,[SP],#4 ;从子程序返回 END

汇编语言与C的混合编程共37页文档

汇编语言与C的混合编程共37页文档
42、只有在人群中间,才能认识自育; 而要挑战别人所说的话,则需要头脑。—— 玛丽·佩蒂博恩·普尔
44、卓越的人一大优点是:在不利与艰 难的遭遇里百折不饶。——贝多芬
45、自己的饭量自己知道。——苏联
汇编语言与C的混合编程
46、法律有权打破平静。——马·格林 47、在一千磅法律里,没有一盎司仁 爱。— —英国
48、法律一多,公正就少。——托·富 勒 49、犯罪总是以惩罚相补偿;只有处 罚才能 使犯罪 得到偿 还。— —达雷 尔
50、弱者比强者更能得到法律的保护 。—— 威·厄尔
41、学问是异常珍贵的东西,从任何源泉吸 收都不可耻。——阿卜·日·法拉兹

汇编语言与C的混合编程

汇编语言与C的混合编程

Turbo C 2.0在处理汇编语句时要调用TASM.EXE。如果没有 TASM汇编器,可以用Microsoft公司的MASM.EXE来替代。具 体的方法有3种: (1)用pctools或debug在tcc.exe中查找到TASM,并替 换成MASM。 (2)把MASM.EXE拷贝或改名为TASM.EXE,放到Turbo C 子目录中。 (3)在命令行输入以下内容:tcc –b –e /path/masm/exec语言源文件名,其中,-b是使用汇编开 关,-e是使用另一个汇编器开关,path是MASM或其他的汇 编器所在的目录路径。
8.1.1 嵌入汇编语句格式 在Turbo C中,C程序中嵌入汇编语言语句必须以关键 字ASM开头,其格式如下: ASM <操作码> <操作数> <;或回车换行>/*注释*/ 在使用此种格式时,应注意以下几点: (1)ASM作为关键字不能省略,带有ASM标识的汇 编语言代码可以看成是C语言的部分程序代码。当C 语言编译器遇到ASM语句时会识别并自动调用汇编语 言编译程序,将它翻译为机器码再嵌入到C语言程序 之中。 (2)操作码可以是处理器指令(如PUSH、MOV等), 也可以是伪指令(如DB、DW、EXTERN等)。
(5)嵌入的汇编语句的注释方式必须采用C语言的 注释方式,即必须用“/*”标识注释的开始,用 “*/”来标识注释的结束,绝不能像纯汇编那样使 用“;”来作为一条注释的开始。 (6)如果要在C语言程序中嵌入连续多条汇编语句, 可以在每行前面都加上“ASM”关键字,更简单的 办法是输入一个ASM关键字后,使用括号"{"和"}"将 这些汇编语句括起来。
本章要点
混合编程是指使用两种或两种以上的程序设计 语言,通过相互调用、参数传递、共享数据结 构和数据信息而形成程序的过程。采用高级语 言与汇编语言混合编程,从而充分利用各种程 序设计语言各自的优势,即程序的大部分采用 高级语言编写,以提高程序的开发效率;在某 些部分利用汇编语言编写,以提高程序的运行 效率。 Turbo C嵌入汇编方式 Turbo C模块连接方式 汇编语言在Visual C++中的应用
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• 第1个寄存器列表中的寄存器用于存放输入的参数。 • 第2个寄存器列表中的寄存器用于存放返回的结果。 • 第3个寄存器列表中的寄存器的内容可能被所调用
的子程序破坏,即这些寄存器是供所调用的子程 序作为工作寄存器的。
2020/12/10
9
2内嵌的汇编器和armasm的区别
• 与armasm相比,内嵌的汇编器在功能和使用方法上主要 有以下特点:
开成几条指令。例如指令: • ADD R0,R0,#1023 • 可能会被展开成下面的指令序列 • ADD R0,R0,#1024 • SUB R0,R0,#01 • 乘法指令MUL可能会被展开成一系列的加法操作和移位操作。 • 事实上,除了与协处理器相关的指令外,大部分的ARM指令和
Thumb指令中包含常量操作数都可能被展开成多条指令。
器的值,用户不需要去保护和恢复这些寄存器的值。
• 用户可以改变处理器模式,但是编译器并不了解处理器模式的改变。 这样,如果用户改变了处理器模式,将不能使用原来的C表达式;重 新恢复到原来的处理器模式后,才能再使用这些C表达式。
2020/12/10
11
3在C程序中使用内嵌的汇编指令
• 3.1在C程序中使用内嵌的汇编指令的语法格式 • 在ARM C语言程序中使用关键词_asm来标识一段汇编指令程序,其格式如下: • _asm •{ • Instruction[;instruction] • …… • [instruction] •} • 其中,如果一行中有很多个汇编指令,则指令之间使用分号“;”隔开。如
• 通常推荐在内嵌的汇编指令中不要指定物理寄存器,因为这可能会影 响编译器分配寄存器,进而可能影响代码的效率。
2020/12/10
4
1.3常量
• 在内嵌的汇编指令中,常量前的符号#可以省略。如果在一个表达式 前使用#,则该表达式必须是一个#。
• 1.4指令展开 • 内嵌的汇编指令中如果包含常量操作数,则该指令可能会被汇编器展
因此在使用这些编译器时要非常小心。
2020/12/10
10

• CPSR寄存器中的NZCV条件标志位可能会被编译器破坏,因此在指 令中使用这些标志位时要非常小心。
• 指令中使用的C变量不要与任何物理寄存器同名,否则会造成混乱。 • LDM与STM指令的寄存器列表中只能使用物理寄存器,不能使用C表
达式。 • 指令不能写寄存器PC。 • 不支持指令BX及BLX。 • 用户不要维护数据栈。通常编译器根据需要自动保存和回复工作寄存
果一条指令占多行,则要使用续行符号“\”。在汇编语言中可以使用C语言的 注释语句。 • ARM C++程序中除了可以使用关键词_asm来标识一段汇编指令程序外,还 可以使用关键词asm来标识一段汇编指令程序,其格式如下: • asm(“instruction[;instruction]”); • 其中,asm后面的括号中必须是一个单独的字符串;该字符串中不能包含注 释语句。
嵌入式系统中汇编语言与C语 言的混合编程
2020/12/10
1
1内嵌汇编器
• 内嵌汇编器指的是包含在C编译器中的汇编 器。使用内嵌汇编器后,就可以在C源程序 中直接使用大部分的ARM指令和Thumb指 令,可以在C程序中实现C语言不能够完成 的一些操作,同时程序的代码效率也比较 高。
• 内嵌汇编器的汇编指令包括大部分ARM指 令和Thumb指令,但由于它嵌入在C程序中 使用,故在用法上有一些特点。
• 在内嵌的汇编指令中使用物理寄存器有一下限制: • 不能直接向PC寄存器中赋值,程序的跳转只能通过B指令和BL指令实
现。 • 在使用物理寄存器的内嵌汇编指令中,不要使用过于复杂的C表达式,
因为当表达式过于复杂时,将会需要较多的物理寄存器,这些寄存器 可能与指令中的物理寄存器的使用冲突。 • 编译器可能会使用R1寄存器或者R13寄存器存放编译的中间结果,在 计算表达式值时可能会将寄存器R0~R3、R2以及R14用于子程序的调 用。因此在内嵌的汇编指令中,不要将这些寄存器同时指定为指令中 的物理寄存器。 • 在内嵌的汇编指令中使用物理寄存器时,如果有C变量使用了该物理 寄存器,编译器将在合适的时候保存并恢复该变量的值。需要注意的 是,当寄存器sp、sl、fp以及sb用做特定的用途时,编译器不能恢复 这些寄存器的值。
2020/12/10
5
• 各展开的指令对于CPSR寄存器中的各条件 标志位的影响如下:
• 算术指令可以正确地设置CPSR寄存器中的 NZCV条件标志位。
• 逻辑指令可以正确地设置CPSR寄存器中的 NZ条件标志位、不映像V条件标志位和破 坏C条件标志位。
2020/12/10
6
1.5标号
• C程序中的标号可以被内嵌的汇编指令使用。 但是只有指令B可以使用C程序中的标号, 指令BL不能使用C程序中的标号。指令B使 用C/C++程序中的标号时语法格式如下:
2020/12/10
2
1.1操作数
• 内嵌的汇编指令中作为操作数的寄存器和常量可 以是C表达式。这些表达式可以是char、short或 者int类型,而且这些表达式都是作为无符号数进 行操作。如果需要带符号数,则用户需要自己处 理与符号有关的操作。编译器将会计算这些表达 式的值,并为其分配寄存器。
• 使用内嵌的汇编器,不能通过寄存器PC返回当前指令的 地址。
• 内嵌的汇编器不支持伪指令“LDR Rn,=expression”, 这条伪指令可以用指令“MOV Rn,expression”来代替。
• 不支持标号表达式。 • 不支持ADR、ADRL伪指令。 • 十六进制数钱要使用前缀Ox,不能使用&。 • 编译器可能使用寄存器R0~R3、ip及例如存放中间结果,
• B{cond} label
2020/12/10
7
1.6内存单元的分配
• 所用的分配都是通过C程序完成的,分配的 内存单元通过变量供内嵌的汇编器使用。
• 内嵌汇编器不支持汇编语言中用于内存分 配的伪操作。
2020/12/10
8
1.7SWI和BL指令的使用
• 在内嵌的SWI和BL指令中,除了正常的操作数域 外,还必须增加下面3个可选的寄存器列表。
• 当汇编指令中同时用到了物理寄存器和C的表达 式时,要注意使用的表达式不要过于复杂。因为 表达式过于复杂时,将会需要较多的物理寄存器, 这些寄存器可能与指令中的物理寄存器的使用冲 突。当编译器发现了寄存器的分配冲突时,会产 生相应的错误信息,报告寄存器分配冲突。
2020/12/10
3
1.2物理寄存器
相关文档
最新文档