汇编程序范文
时间:2023-03-27 01:53:49
导语:如何才能写好一篇汇编程序,这就需要搜集整理更多的资料和文献,欢迎阅读由公务员之家整理的十篇范文,供你借鉴。
篇1
AT&T 汇编指令
同DOS/Windows 下使用的Intel 风格的汇编语言不同,在Linux 系统中,更多的是采用AT&T 格式。两者的汇编指令名类似,但在语法格式上有着较大的不同。
1.在AT&T汇编中,寄存器名要加'%'前缀;而在Intel汇编中,寄存器名不需要加前缀。
2.在AT&T汇编中,用'$'前缀表示一个立即数;在Intel 汇编中,立即数不用任何前缀。
3.在 AT&T 汇编格式中,目标操作数在源操作数的右边;而在 Intel 汇编中,顺序相反。指令举例如下:
AT&T 格式:addl $0x80, %eax
Intel 格式: add eax, 80h
4.在 AT&T 汇编格式中,操作数的字长由操作符的最后一个字母决定,后缀'b'、'w'、'l'分别表示操作数为字节(byte,8 bit)、字(word,16 bit)和长字(long,32 bit);而在 Intel 汇编格式中,操作数的字长是用 "byte ptr" 和 "word ptr" 等前缀来表示的。例如:
AT&T格式: movb $0x32, %al
Intel格式: mov al, byte ptr 32h
5.在 AT&T 汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上'$'作为前缀,而在 Intel 格式中则不需要。 远程转移指令和远程子调用指令的操作码,在 AT&T 汇编格式中为 "ljump" 和 "lcall",而在 Intel 汇编格式中则为 "jmp far" 和 "call far",即:
AT&T格式:ljump $section, $offset
Intel格式:jmp far section:offset
与之相应的远程返回指令则为:
AT&T格式: lret $stack_adjust
Intel格式:ret far stack_adjust
6.在 AT&T 汇编格式中,内存操作数的寻址方式是:section:disp(base, index, scale) 而在 Intel 汇编格式中,内存操作数的寻址方式为: section:[base + index*scale + disp]
7.由于 Linux 工作在保护模式下,用的是 32 位线性地址,所以在计算地址时不用考虑段基址和偏移量,其地址计算方法为:disp + base + index * scale。两种格式对比举例如下:
扬声器汇编程序开发
Linux 是一个运行在保护模式下的 32 位操作系统,采用 flat memory 模式,目前最常用到的是 ELF 格式的二进制代码。一个 ELF 格式的可执行程序通常划分为如下几个部分:.text、.data 和 .bss,其中 .text 是只读的代码区,.data 是可读可写的数据区,而 .bss 则是可读可写且没有初始化的数据区。代码区和数据区在 ELF 中统称为 section,根据实际需要你可以使用其它标准的 section,也可以添加自定义 section,但一个 ELF 可执行程序至少应该有一个 .text 部分。
扬声器发声程序主要是通过I/O端口的数据读写完成的,由于Linux 是一个运行在保护模式下的32 位操作系统,系统默认情况下不能直接对I/O端口进行读写。在程序进行I/O端口读写前,首先要请求Linux系统开放(允许读写)相应的I/O端口,同时还应该注意在程序结束前提请系统关闭开放的I/O端口。对I/O端口的开放/关闭操作可以使用Linux系统功能调用(0x80号中断)的101号功能。开发AT&T 汇编语言程序包括编辑源程序、汇编、连接、调试运行等步骤。
启动Linux下的文本编辑器,编辑输入AT&T 汇编语言源程序。这里介绍的扬声器汇编源程序如下,需要注意的是,在AT&T 汇编语言源程序中用“#”标记注释,也可以C语言一样用“/* */”作为注释标识符。
data #以下定义数据区数据
# frequency 存储的为1,2,3,4,5,6,7七个音符(中音)和高音1的频率,0为结束标志
frequency: .word524,588,660,698,784,880,988,1048,0
timeslice: .word 15000,15000,15000,15000,15000,15000,15000,45000
text#以下定义代码区
此处的_start相当于C语言中的main()函数,定义为全局型
global _start
_start:
#请求系统开放0x42、0x43端口
movl $101,%eax#系统功能号
movl $0x42,%ebx #起始端口号
movl $0x02,%ecx #端口个数
movl $1,%edx#允许用户使用
int $0x80 #系统功能调用中断
#请求系统开放0x61端口,允许用户程序读写
movl $101,%eax
movl $0x61,%ebx
movl $0x01,%ecx
movl $1,%edx
int $0x80
#获取频率、时长数据的起始地址
movl $frequency,%esi
movl $timeslice,%edi
load_data:
pushl %edi
#取频率值,为0则结束
movw (%esi),%di
cmpw$0,%di
je finished
#根据频率值求对应的计数值
movw $0x12,%dx
movw $0x3280,%ax
div %di
popl %edi
call sound_on #转发声子程序
#调整指针寄存器的值
addl $2,%esi
addl $2,%edi
jmp load_data#循环取下一组声音值
finished:#准备结束程序
popl %edi
#关闭扬声器
inb $0x61,%al
andb $0xfc,%al
outb %al,$0x61
#关闭0x42、0x43端口
movl $101,%eax#系统功能号
movl $0x42,%ebx #起始端口号
movl $0x02,%ecx #端口个数
movl $0,%edx#允许用户使用
int $0x80 #系统功能调用中断
#关闭0x61端口,禁止用户程序读写
movl $101,%eax
movl $0x61,%ebx
movl $0x01,%ecx
movl $1,%edx
int $0x80
#1号系统功能调用,结束本程序
movl $0,%ebx #结束返回码
movl $1,%eax
int$0x80
#主程序到此结束
sound_on:#发声子程序开始
pushl %eax
#选择定时器2
movb $0xb6,%al
outb %al,$0x43
popl %eax
#向计时器2依次写入2个字节计数值
outb %al,$0x42
movb %ah,%al
outb %al,$0x42
inb $0x61,%al
#打开扬声器
orb $3,%al
outb %al,$0x61
#声音播放的延时
movw (%edi),%bx
wait1:
movl $39480,%ecx
delay:loop delay
dec %bx
jnz wait1
ret #子程序返回
#扬声器汇编程序结束
源程序程序输入完毕,以纯文本格式保存。Linux 系统下的汇编语言源程序扩展名通常为“.s”,程序员也可以自行设定扩展名。本示例的汇编源程序文件名为speaker.s。
将源程序编译为目标代码
用 AT&T 格式编写的汇编程序源文件输入完毕,接下来的工作就要使用汇编器将源程序文件编译。汇编器(assembler)的作用是将用汇编语言编写的源程序转换成二进制形式的目标代码。Linux 平台的标准汇编器是 GAS,它是 GCC 所依赖的后台汇编工具,通常包含在 binutils 软件包中。GAS 使用标准的 AT&T 汇编语法,可以用来汇编用 AT&T 格式编写的汇编语言程序。在Linux 系统终端窗口中输入以下格式的命令:
[root@sunqd]$ as -o speaker.o speaker.s
其中的斜体部分为输入的命令,此命令将当前文件夹(sunny)下的speaker.s汇编程序转换为二进制形式的目标代码文件名speaker.o。汇编器GAS能够发现汇编源程序中的语法错误,在屏幕上列出错误行号和相关的错误提示信息。
连接生成可执行程序
由汇编器产生的目标代码是不能直接在计算机上运行的,它必须经过连接器的处理才能生成可执行代码。连接器可以将多个目标代码文件连接成一个可执行代码文件,这样可以先将整个程序分成几个模块来单独开发,然后才将它们组合(连接)成一个应用程序。 Linux 使用 ld 作为标准的连接程序,它同样也包含在 binutils 软件包中。汇编语言源程序在成功通过 GAS 或 其它汇编器的编译并生成二进制目标代码后,就可以使用 ld 将其连接成可执行程序了。在Linux 系统终端窗口中输入以下格式的命令:
[root@sunqd]$ ld -s -o speakerspeaker.o
该命令将目标代码文件speaker.o连接为可执行程序speaker,如果发现错误,则连接程序ld将提示相关的错误信息;如果没有看到错误提示信息,则说明已经生成在Linux 系统中运行生成的可执行程序了。
运行可执行程序
若要运行生成的可执行程序,只需在在Linux 系统终端窗口中输入可执行文件名即可。运行我们的扬声器的示例程序,可以输入如下命令:
篇2
关键词:汇编语言;C语言;混合编程
汇编语言的优势就是速度快,占用存储空间不大,而且可以随时控制硬件,这些优点是其它的程序语言无法取代的。汇编语言也有不足之处,就是在高级程序的编写与调试时存在着较大的困难,特别是在处理一些数据或者一些混合运算时显得更加困难。
C语言,它的优势就是在于功能全面,表达形式多样且灵活,开发使用效率很高,具有其它高级语言无法具有的优势。通常在软件开发过程中,大部分程序采用高级语言编写,以提高程序的开发效率;但在要求执行速度快、占用空间少或要求直接控制硬件的场合,则利用汇编语言编写,以提高程序的运行效率。
1.汇编语言和C语言混合编程的方法
C语言和汇编语言混合编程的具体方法有以下几种。
2.1 参数传递
汇编语言程序和C语言程序在调用时会涉及到参数传递,一般采用堆栈进行传递。在汇编语言中将BP作为基址寄存器,调用程序先将来自于C语言程序中的参数依次压入堆栈中,然后当需要使用这些参数时,再用BP加上不同的偏移量依次对堆栈中的数据进行存取操作。
2.2 调用关系的确定
对于将要涉及到调用的过程或函数需要事先说明和建立调用与被调用关系。被调用的过程或函数应预先说明为外部类型,以便被外部模块引用,而调用程序也需要在程序中说明将要引用的外部模块的名称。在说明调用关系时还应根据不同的存储模式确定相应的汇编语言格式。C程序小模式对应汇编程序的近类型过程,而C程序大模式则对应汇 编程序的远类型过程。
总而言之,汇编语言和C语言的混合编程方法可以使汇编语言与C语言之间取长补短,充分发挥各自优势,相互交叉调用,进行参数传递,共享数据信息和数据结构,使由此开发的软件更实用、更安全可靠,使开发和编程工作达到事半功倍的效果。
参考文献:
[1] 罗南超,向昌成,李唐辉. 汇编语言实现多种进制的通用输入输出[J]电脑知识与技术, 2008,(36) .
[2] 崔卫东. VC++与汇编语言混合编程的研究与实现[J]福建电脑, 2007,(05) .
[3] 宋金华. 汇编语言和C语言在图形处理中的综合应用[J]湖北广播电视大学学报, 2010,(12) .
篇3
关键词:汇编程序;C语言;编排技术
1 引言
在平常编写程序时,我们一般都希望选择C、Pascal、Basic等这样的高级语言来编写,高级语言由于有编译器的支持,它们的语法更接近于自然语言,表达能力强,使用灵活,具有强大的库函数,更重要的是高级语言与机器无关,可移殖性较好,这样使程序开发周期比较短,省时省力。为了提高程序运行速度,或直接访问硬件,用汇编语言编程可以提高程序的运行效率。为了既能缩短程序开发周期,又能保证程序的执行效率,较好的解决办法是程序的框架或主体部分用C语言编写,要求执行效率高的部分用汇编语言编写。这里就涉及到了混合编程的问题,这种混合编程的方法将C语言和汇编语言的优点结合起来,所以成为目前单片机开发最流行的编程方法。混合编程的关键是解决好高级语言与汇编语言的接口问题,可采用两种方法:一是使用嵌入式汇编,即在高级语言的语句中直接使用汇编语句,这种方法比较简洁直观,但功能较弱;另一种方法是独立编程,分别产生各自的目标文件,然后经过连接,形成一个完整的程序。
2 汇编语言和C语言程序的变量相互调用
在一个工程中,一般都会由多个汇编文件和多个C/C++程序文件有机组成。在这些汇编文件和C/C++文件之间就存在变量相互访问和函数相互调用的问题。内嵌汇编不用单独编辑汇编语言文件,比较简洁,但是有诸多限制,当汇编的代码较多时一般放在单独的汇编文件中。这时就需要在汇编和C之间进行一些数据的传递,最简便的办法就是使用全局变量。
2.1 汇编程序中访问C程序变量
在C/C++程序中声明的全局变量可以被汇编程序通过地址间接访问。具体访问方法/步骤如下:
①C/C++程序中声明全局变量;②在汇编程序使用IMPORT/EXTERN伪指令声明引用该全局变量;③使用LDR伪指令读取该变量的内存地址;④根据该数据的类型使用相应的LDR或STR指令读取或设置该变量的值。对于无符号变量,使用LDRB/STRB访问char;使用LDRH/STRH访问short;使用LDR/STR访问integer。对于有符号数,使用LDRSB/LDRSH。
在汇编的源程序中调用C语言风格的字符串需要使用IMPORT伪操作。IMPORT相当于C语言中的extern关键字,告诉编译器引用的符号不是在本文件中定义的,而是在其他的源文件中定义的。
伪操作的格式:
IMPORT symbol[,WEAK]
symbol是声明的符号的名称;[,WEAK]指示编译器如果发现symbol在所有的源文件中都没有找到,那么它也不会产生任何的错误信息。
2.2 C程序中访问汇编程序变量
在汇编程序中声明的数据可以被C/C++程序所访问,具体访问方法/步骤是:在汇编程序中用EX-PORT/GLOBAL伪指令声明该符号为全局标号,可以被其他文件应用;C/C++程序中定义相应数据类型的指针变量;对该指针变量赋值为汇编程序中的全局标号,利用该指针访问汇编程序中的数据。
3 汇编语言和C语言程序相互调用
3.1 在C程序中调用汇编函数
在C程序中调用汇编函数一般情况下,在C中要调用一个汇编编写的函数,需要首先在C语言中声明此函数的函数原型,同时C语言希望所有的外部标号均以下划线/_0开头,如果汇编模块中定义的函数及变量准备供C调用,应以下划线开头。如若有函数F_Sub,要定义为供C调用的函数,在汇编程序中应定义为PUBLIC _F_Sub。因为C语言区别对待大小写字母,所以在编写准备与C模块相连接的汇编模块时,应该注意符号名的大小写,以便保持一致。以下是在C中调用汇编程序的实例:
//C语言主函数main()
void F_Sub(void); //声明要调用的函数的函数原型,此函数无参数传递
intmain(void){
while(1)
F_Sub(); //调用汇编函数
return 0;
}
//汇编子函数F_Sub()
.CODE
. PUBLIC _F_Sub
_F_Sub:
NOP
RETF
以上程序在IDE集成开发环境下编译连接后即可运行。
3.2 在汇编程序中调用C函数
在汇编函数中要调用C语言的子函数,应该根据C函数原型所要求的参数类型,分别把参数压入堆栈后,再调用C函数。调用结束后还须再进行弹栈,以恢复调用C函数前的堆栈指针。以下是汇编调用C函数的。
例如下面的程序,利用函数调用形式输出字符串″Hello world e″
Extern void display(void)L
Main()
{
display()L
}
.model small
.data
string db ″Hello world e$″
.code
public _display
_display proc
mov ah,9
mov dx,offset string
int 21h
ret
_display endp
end
说明:①在C程序中使用关键字″extern″对函数作显式说明;②对不同的存储模式要选用不同的汇编语言格式。当C程序为微型、小型、紧凑型模式时,汇编用近过程;当C程序为中型、大型、巨型模式时,汇编用远过程;③汇编程序取C的参数。远过程返回地址占四个字节,BP压入占二字节,所以第一个参数在BP+6所指向的单元,而近过程第一个参数在BP+4所指向的单元;④汇编程序中寄存器的保护。TurboC允许子过程使用SI 和DI存放局部变量,当寄存器变量多于两个时,多余部分会自动转到堆栈中存储。因此,汇编过程的格式为:
PUSH BP
MOV BP,SP
PUSH DI
PUSH SI…
…………
…………
…………
POP SI
POP DI
POP BP
RET
⑤返回值。每种C语言的数据类型都有一个标准的返回位置,一般在AX (微型、小型、紧凑型模式)或DX:AX(中型、大型、巨型模式)中,如:char,unsigned char,short int等,返回值位置为AX,且返回数据必须放置在RET指令之前。汇编子程序要定义为远过程,并用public伪指令把过程名定义为公共。
4 结束语
本文研究了汇编语言与C语言混合编程的编程问题,重点对编程时C语言与汇编语言和C语言变量与程序的相互调用问题进行了分析,并给出了实例。当采用两种或两种以上的编程语言组合编程,彼此相互调用,进行参数传递,是一种有效的程序设计方法。这种方法可以发挥各种语言的优势和特点,充分利用现有的多种实用程序、库程序等,使软件的开发周期大大缩短,是当前程序接口技术的一个重要研究和应用领域。
[参考文献]
[1]沈美明,温冬婵.IBM-PC汇编语言程序设计[M].北京:清华大学出版社, 2001.
篇4
【关键词】编译器 语言 编译模式 语言教学
在大学课程的教学中,计算机语言是学生的必修课程之一,计算机语言教学是让学生掌握计算机语言的特征,学会使用计算机语言进行程序设计的基本技能。目前,大学里开设的计算机教学语言主要有Basic、C、C++、Java、C#、汇编等多种语言。但普遍存在的问题是学生在学习了一门或多门计算机语言后,并不了解源程序在计算机内部是怎样工作的,怎样被计算机系统执行,本文以计算机语言的编译器执行为主线,剖析计算机语言的执行过程,希望对计算机语言的教学有所启发。
1 高级语言程序的翻译方式
一个高级语言程序的执行,必须依赖于相应的翻译系统,也就是说计算机高级语言不能直接被计算机执行,需要由编译器或解释器翻译成低级语言或二进制语言后才能执行。高级语言程序的执行通常有编译方式和解释方式两种。
1.1 编译方式
高级语言编写的源程序在计算机中的处理过程为:源代码 (source code) 预处理器 (preprocessor) 编译器 (compiler) 汇编程序 (assembler) 目标代码 (object code) 链接器 (Linker) 可执行程序 (executables)。
1.2 解释方式
解释器是不同于编译器的另一类语言处理器。解释器直接执行源程序所指定的运算,不生成目标程序。解释器也需要对源程序进行词法分析、语法分析、和语义分析。对于编译方式来说,对源程序的词法分析、语法分析和语义分析只要进行一次。而对于解释方式来说,每次执行到源程序的某个语句,都要对它进行一次词法分析、语法分析和语义分析,确定了这个语句的含义后,才能执行它指定的运算,因此解释执行的效率比编译器生成的机器代码的执行效率低。
典型的以解释方式执行的高级程序设计语言有BASIC和PROLOG。
2 其他翻译程序
2.1 汇编程序
汇编程序是系统软件中语言处理系统软件。当源程序是汇编语言程序,目标程序是机器语言程序时,翻译程序称为汇编程序。检查源程序;测出源程序中的语法错误,并给出出错信息是汇编程序的主要功能;产生源程序的目标程序,给出列表文件;展开宏指令。
2.2 交叉编译程序
当源程序是高级语言程序,目标程序是另一台机器的机器语言程序或者汇编语言程序时,翻译程序称为交叉编译程序。
2.3 反编译程序
当源程序是机器语言程序,目标程序是高级语言程序时,翻译程序称为反编译程序。反编译程序通常用来将一段机器代码翻译成高级语言代码,以便对这段程序进行分析和改造。
2.4 并行编译程序
当源程序是串行执行的高级语言程序,目标程序是并行执行的机器语言程序或汇编语言程序时,翻译程序被称为并行编译程序。这种编译程序通常依赖于计算机的体系结构。
另外,还有一些强调某一方面功能的编译程序。例如,诊断程序编译程序、优化编译程序、可变目标编译程序等。
3 计算机教学语言的执行方式
3.1 BASIC语言
BASIC语言是由 Dartmouth 学院 J. Kemeny 与 T. Kurtz 两位教授于20世纪60年代中期所创。早期BASIC 语言的执行采用的是解释方式,它不需要在运行前先把源程序翻译成目标代码,而是将源程序逐句翻译成机器语言程序,译出一句就立即执行,即边翻译边执行,这种方式便于程序的调试和修改,但运行速度慢。
3.2 C语言
一个C源程序可分成若干个模块,存储在不同的文件中。C编译系统对这些源文件分别进行预处理、编译和汇编,形成可重定位的目标文件;然后再利用连接器将这些目标文件和必要的库文件连接成一个可执行的目标文件,即具有绝对地址的机器代码。
3.3 JAVA语言
Java语言是一种跨平台的编程语言。Java虚拟机技术是实现Java平台无关性特点的关键。Java源程序被编译成与任何计算机体系结构都无关的中间代码――Java虚拟机语言(JVML语言),任何机器只要安装了Java运行系统就能够运行这种中间代码。
由于JVML语言平台无关的特点,JVML程序的装载、连接、编译过程与传统编程语言的编译过程相比更具有动态性。即时编译器以一个方法为单位进行编译,能够生成较高质量的代码,使生成的代码的执行速度可达到解释执行的10倍。因此即时编译器的出现使Java程序的执行效率得到了很大提高。
3.4 面向对象语言
面向对象方法是一种新的构造软件的思维方法、分析方法和设计方法。
3.5 汇编语言
汇编语言是电子计算机硬、软件及应用专业学生必修的核心课之一,是为特定计算机或计算机系列设计的一种面向机器的语言,由汇编执行指令和汇编伪指令组成。使用汇编语言编写的程序,机器不能直接识别,由汇编程序将汇编语言翻译成机器语言。
在计算机上运行汇编语言程序的步骤为:用编辑程序建立ASM源文件;用ASM程序把ASM文件转换成OBJ文件;用LINK程序把OBJ文件转换成EXE文件;执行EXE文件。
4 结束语
目前,国内很多大学都开设了各种计算机语言类课程的教学,正确理解计算机程序设计语言的执行过程与翻译模式对于计算机语言教学与编译程序的理解具有重要意义。
参考文献
[1]邹爱萍.Buck型DCDC开关电源芯片工作原理分析[J].电源技术应用,2013(05) 13-14.
作者简介
刘凯(1985-),男,山西省离石人。硕士研究生学历。现为吕梁学院计算机科学与技术系助教。研究方向为网络与信息安全、软件工程。
薛艳锋(1984-),男,山西省临县人,硕士研究生学历。现为吕梁学院计算机科学与技术系讲师。研究方向为数据挖掘。
篇5
一、变量与函数的相互调用
c语言可以调用汇编子程序和汇编语言中定义的变量。但要注意由于。编译后的目标文件自动地在函数名和变量名前加一个下划线,所以在汇编语言中调用C语言的函数和变量时,应在函数名和变量名前加一下划线。在汇编语言程序开始部分,应对调用的函数和变量用EXTERN加以说明。
二、调用者与被调用者的参数传递
这种数据传递通过堆栈完成,在执行调用时从调用程序参数表中的最后一个参数开始,即从右到左自动依次压人堆栈;将所有参数压人堆栈后,再自动将被调用程序执行结束后的返回地址(断点)压人堆栈,以使被调程序结束后能返回主调程序的正确位置而继续执行。进人汇编子程序后,为了能正确获取主调程序并存人堆栈中的数据,被调的汇编子程序先后要做如下一些工作:
l、保存sp的副本进人汇编子程序后,子程序中免不了要有压栈和出栈的操作,故sP时刻在变化。为了能用SP访问堆栈中的参数,安全办法是一进人子程序后,先为SP制副本,以后对传递参数的访问都用副本进行。一般可用BP保存SP,如:pushbPmovbP,sp
2、保留数据空间如果汇编子程序中需要一些局部数据,可以简单地减小SP的值,以便在栈空间中保留出一段存贮区,用于存放局部数据,该区域须在子程序结束后恢复。如下语句可以保留一个局部数据区:pushbPmovbP,spsubsp,spaee;设spaee=4如上语句段中,SPACE是局部数据的总字节数。在以后的应用中,由于SP是变化的,而BP是固定的,用负偏移量可以存取局部变量。上例利用BP及偏移量,将两个字的局部数据初始化为0。
3、保留寄存器值如果在被调子程序中用到sI、DI等其它寄存器,则应先把它们压人堆栈,以保留寄存器原值。例如,下例就是将SI和DI寄存器的值压栈:pushbpmoybp,SpsubSp,sPaeePush51Pushdi
4、获取传递参数BP保留了SP在参数传递完并将BP压栈后的一个副本,利用BP可以很方便地访问各参数。现假设调用了名为funcl汇编程序模块的主函数:maln(){……fund(pl,pZ,p3);……}。各参数都是2字节的整数值,返回地址retumaddress,在小模式编译方式共占用2个字节。如果要将传递的参数p卜pZ、p3取出,并分别赋给bx、Cx、dx寄存器,可由下列语句完成这一功能:movbx,[bp+4jmovcx,[bp+6]movdx,[bp+8〕
篇6
引言
随着信息技术的发展,电视信号的数字化编码、数字化存储、数字化处理已经越来越广泛。新开发的数字有限电视广播系统主要包括MPEG-2编码器、数字传输复用器、数字调制器以及机顶盒。复用器是该系统的重要组成部分,完成对多路符合MPEG-2系统层标准ITU-TREC.H.222.1|ISO/IEC13818-1的TS流(Transport Stream)的复用,经过64 QAM调制后,以便在1路6MHx的带宽中传送多路数字化节目。考虑到处理的实时性,我们使用美国德州仪器公司(TI)的TMS320C5402(简称C5402)DSP作为主控芯片。本文首先介绍TS流的结构、C5402芯片、复有器的组成,然后重点介绍该芯片在复用器的应用,最后就利用CCS开发仿真器一经验介绍。
1 TS流简介
主要包括分组方法、程序特殊信息(PSI)表以及程序参考时钟(PCR)的提取。
(1)分组方法
传送流分组长度固定为188字节,分组由分组首部及有效负载组成,如图1所示。
(2)PSI
PSI被分成4类表。如表1所示,每个表可被分成1段或多段置于传送流中。这4类表是:程序关联表PAT(Program Association Table)、程序映射表PMT(Program Map Table)、网络信表NIT(Network Information Table)、条件访问表CAT(Conditional Access Table)。这4类表中包含进行多路解调和显示程序的必要和足够的信息。
表1 程序特殊信息
结构名流类型保留的PID#描 述程序关联表ITU-T Rec.H.222.0|
ISO/IEC 13818-10x00关联程序号与程序映射表PID程序映射表ITU-T Rec.H.222.0|
ISO/IEC 13818-1赋值的说明1个或多个程序组成部分的PID值网络信息表私用赋值的物理网络参数:FDM频率、发送器号码等等条件访问表ITU-TRec.H.222.0|
ISO/IEC 13818-10x01建立1个或多个(私用)EMM流与每个独立的PID值的联系系统层解复用,首先要获取PAT表。PAT表中包含了该传送流中所有程序的一个清单。通过PAT表,就可获取该传送中所包含每个程序的PMT表。
在每个程序的PMT表中,就有该程序中各个原始流的信息,包括PID、原始流类型以及该程序中包含有效PCR字段的传送流中PID。通过PAT及PMT表,就可掌握传送流中每个程序以及每个程序中各原始之间的关系。
(3)PCR
在传送流中,解码的同步实现是靠相应的程序参考时间PCR值。PCR是将比特流本身的时序编码的时间标签,它可以由同一道程序的视频和音频的PTS所用的共同时间基点推出。由于每道程序都有自己的时间基点,所以含有多道程序的传送流的每一道程序都有独立的PCR字段。
2 C5402介绍
C5402是TI公司1999年10月推出的性价比较高的定点数字信号处理器,其主要特点如下:
*先进的改造型哈佛结构,操作速率可达100MIPS;
*先进的多总线结构,3条16位数据存储器总线和1条程序存储器总线;
*40位算术逻辑单元(ALU),包括1个40位桶形移位器和2个40位累加器;
*1个17×17乘法器和1个40位专用加法器,允许16位带(或不带)符号的乘法;
*8个辅助寄存器及1个软件栈,允许使用业界最先进的定点DSP C语言编译器;
*数据/程序寻址空间1M×6bit,内置4K×16bit ROM和16K×16bit RAM。
*内置可编程等待状态发生器、锁相环时钟产生器、2个多通道缓冲串行口、1个8位并行与外部处理器通信的HPI口、2个16位定时器以及6通道DMA控制器;
*低功耗,工作电源有3V和1.8V(内核使用)。
3 复用器硬件框图及流程
复用器硬件框图如图2所示。
(1)合成控制卡(主卡)流程
主卡流程:主要完成6块卡处理的实施监控,生成PSI等信息并周期性发送。主卡的PSI信息:6个PMT的PID以及每个子卡输入来的视频、音频、PCR的PID号是事先规定好的。
(2)单路TS流处理卡(子卡)流程
子卡流程:TS流进入FIFO缓存,由DSP进行PSI信息的提取和码率的计算;将有关信息送入合成处理卡进行分析、综合;根据需要从输入的流中提取1路视频、1路音频和PCR包,并将它们的PID改为事先规定的。子卡的功能相当于一个简易的码流分析仪,而且可以提供1路单独的TS流。
4 C5402的几个典型应用
C5402在该系统中的应用:对输入的TS流进行分析;对6路码流进行均匀交织和PSI信息的重置;主卡与子卡之间通过C5402 HPI接口进行通信;利用C5402串口与计算机RS232串口相连。
4.1 输入的TS流分析
DSP从FIFO中读取TS流到内部RAM中去,如图3所示,根据13位的PID号0x000找到PAT表,在PAT表中获得PMT的ID号和NIT的ID号;根据PMT_PID获得视频、音频、PCR的PID号以及其它私有信息的PID号;根据PCR_PID和pcr_flag,找到PCR包;根据公式计算出码率:
其中i'、i''为相邻2个PCR包,求得多个码率,然后求算术平均,获得平均码率。利用FIFO进行数据传输,速率在10~25MB/s之间。由于DSP处理能力为100MIPS,子卡中DSP传输数据量是大为2MB/s,约耦时0.1~0.2s,这样处理时间足够(0.8~0.9s)。子卡输入FIFO采用8KB大小,在其半满时,DSP等待时间最大为(188/10 000)×6=0.1128ms,期间FIFO的填充量为0.112 8×1=0.112 KB,远不能输入码流将子卡的输入FIFO填充满而导致溢出。
4.2 码流交织和PSI信息配置
为了将6块子卡输入的TS流复合成1路TS流,主卡DSP的功能就是将6路TS流均匀交织。主卡数据通过HPI送到主卡的DSP内部RAM中,再写到外部FIFO中。由于各种码流的PID叫可能相同,需要对各路TS流的ID号进行重新设置。主卡根据预先设置的所有PID生成新的PSI表,并按照一定时间间隔发送到外部的FIFO中去。主卡的CPU以100MHz运行,输出FIFO的大小为8KB,以固定5MHz的码率发送,子卡填写的数据不会导致主卡上溢。当主卡的输出FIFO没有达半满时,填充空包,使FIFO不会下溢。
在子卡中根据分析得到的PSI信息,可以提取1路或者多路的节目流,并将PID号改为事先规定的,通过HPI通信接口传送到主卡。
4.3 HPI接口
HPI(Host Port Interface)接口可以方便地实现主卡与子卡之间的通信,而不需要额外的器件。C5402的HPI操作是8位的。当C5402运行在100MHz主频时,通信速度可达到25MB/s。HPI接口具有3个16bit寄存器:HPIA(地址寄存器)、HPID(数据寄存器)、HPIC(控制寄存器)。主卡与子卡的DSP芯片之间的连接如图4所示:HD0~HD7是8位数据线,直接接到主设备的数据线上;HCS为选通信号;HDS1~HDS2为数据锁存信号,在主设备的存取周期控制数据的传输,一般连到设备的数据选通;HR/W是读写信号;HCNTL0/HCNL1用于主设备选择存取HPI的哪一个寄存器和对寄存器的存取类型,连至主设备的地址线。由于HPI寄存器是16位的,而HPI与主设备仅以8位数据线相连,因而用HBIL决定当前存取的是1个字的第1个字节还是第2个字节,连到主设备地址线。
对HPI操作首先将控制字写入HPIC,然后将要存取的地址写入HPIA,最后丰取HPID,就可从HPI存储块或将数据写入HPI存储块。此外,还可选择HPIA自动增加方式,将初始地址写入HPIA,可不再操作HPIA,每存取1次数据,地址都会自动加1,因而加快了存取速度。
4.4 主卡DSP与计算机接口
为了实现系统自检、码率以及节目信息提取、输出,我们通过DSP的串口与计算机的串口进行通信。如图5所示,采用的是异步通信方式。其中75C189和75C188为电平转换芯片,C5402有2个McBSP(多通道缓冲串行口)。McBSP提供了全双工的通信制以及双缓存的发送寄存器和三级存的接收寄存器,允许连续的数据流传输,数据长度可以为8、12、16、20、24、32;同时还提供了A-律和μ-律压扩,多达128个通道的发送和接收。数据经McBSP与外设的通信通过DR和DX引脚相连。控制信号则由CLKX、CLKR、FSX、FSR四条引脚来实现。
4.5 DSP程序BOOTL0ADER的实现
BOOTLOADER是为了在上电时,将用户代码从外部加载到内部的存储器以加快运行速度。我们使用C5402外部8位并行I/O口实现BOOTLOADER程序。C5402读I/O口0xffff,这里面存放着外部存储器的首地址(数据区)。若在这个首地址内读到了关键字08 AA,就进行8位加载;若是10AA则表示16位加载。硬件系统就是加了1片3.3V的Flash,程序用编程器烧入Flash。
5 C5402的软件编程体会
(1)C语言与汇编混合编程
在运算能力不是十分紧张的情况下,用C语言开发DSP程序不仅使DSP开发的速度大大加快,而且开发出来的DSP程序的可读性和可移植性大大加强,程序修改也极为方便。采用C编译器的优化功能可以增加C代码的效率。
一般情况下,采用C语言和汇编混合编程方法有3种:①独立编写C程序和汇编程序;②直接在C语言程序的相应位置嵌入汇编语句;③对C程序进行编译生成相应汇编程序,然后对汇编程序进行手工优化和修改。可以从C程序中访问汇编程序的变量和常量,也可以在汇编程序中访问C程序变量。
(2)预防流水线冲突
流水线操作是DSP实现高速度、高效率的关键技术之一。在TMS320C54X中采用了深度与6级的流水线操作,因此流水线冲突不可避免的。一般情况下,当发生流水线冲突时,由DSP自动插入延迟解剖冲突问题,但有时需要程序员通过调整程序语句的次序或在程序中插入一定量的NOP来解决。例如:
STLM A,BRC
NOP
RPTB LOOP
语句
LOOP
(3)存储空间要正确分配
C5402总共有192K字大小存储空间,64K字的程序区、64K字的数据区和64K字的I/O区。当寄存器PMST的OVLY=0时,片内RAM在数据区内可访问,在程序区不可访问;当OVLY=1时,片内RAM映射到程序区和数据区,但数据页(地址从0H~7FH)不映射到程序空间。我们在程序编程中选用后种模式。程序和数据同一块片内RAM,在编写CMD文件时程序和数据区间不能发生重叠。
(4)指令的使用
①TMS320C54X的汇编有算术指令和程序指令,2种指令可以互换。当外部端口操作时使用端口指令PORTW和PORTR。
②利用DADST和DSADT指令,可以同时在1个累加器中进行2次运算。
③利用DADD和DSUB可实现32的加减法。
④利用CMPS、SACCD、SRCCD、STRCD四个条件存储指令,以减少条件判断指令的开销;利用MAX、MIN、FIRS、LMS可以减少运算所需的指令周期;利用C54的并行指令可以省去多次数据存储,提高编程的效率。
⑤充分利用*(IK)寻址(在数据区内指明所要访问的地址),可以减少辅助寄存器的使用。
(5)少用函数和子程序调用
虽然结构化程序给软件和调试带来方便,但一个函数和子程序的调用和返回都将使C5402产生1次流水线刷新,增加了指令周期,因而在存储空间足够时,应多使用宏结构;但在编程时又必须考虑程序的大小,所以在对设备处理速度影响不大的情况下,也可以使用函数和子程序。
篇7
关键词: C 语言;汇编语言;混合编程
中图分类号:TP313 文献标识码:A 文章编号:1006-4311(2014)24-0231-02
0 引言
汇编语言是一种面向机器的语言,其优点是运行速度快,占用存储空间小,可直接对硬件进行控制。缺点是编写、调试困难、移植性差。C语言简洁、灵活、库函数丰富、调试方便、移植性好,目前已被广泛地应用于系统软件和应用软件的开发中,为了发挥各自优势,取长补短,采用混合编程。大部分程序,如界面、人机接口(外壳程序)、数据处理等用C语言编写,以提高程序的开发效率。而某些程序,如需要缩短程序的运行时间,或需要对硬件进行直接操作,或需要利用操作系统的某些功能模块,或频繁使用的程序、或需要占用内存空间少的程序(内核程序),则用汇编编写,以提高程序的运行效率。
1 嵌入式汇编
嵌入式汇编也称行内汇编,源程序中直接插入汇编语句。汇编语句可直接访问C程序中定义的常量、变量、函数。不必考虑二者之间的接口,方便编程。
1.1 嵌入式汇编语句的格式
格式:asm操作码 操作数[;或换行]
其中:操作数可以是汇编语句中的立即数、寄存器、表达式等还可以是C中的常量、变量、标号等。分号;是汇编语句结束符,并非注解,要用注解,用C的注解。如下例
所示。
1.2 汇编语句访问C的数据
嵌入的汇编语句可以访问C语言程序中的任何标识符,包括变量、常量、标号、函数名、寄存器变量、函数参数等。如下例所示。
1.3 汇编语言与C语言接口规则
1.4 编译过程
命令行键入命令:TCC-B-Iinclude-Llib 文件名.c即可. TCC会自动调用TASM.EXE和TLINK.EXE,并且TLINK.EXE能正确的找到需要的.obj和.lib文件,要保证TC目录下存在TASM.EXE文件。如果单步编译,可能会碰到很多的问题,主要是TLINK.EXE不会自己去找.obj和.lib文件。该命令的功能是:.C编译TCC.ASM汇编TASM.OBJ连接TLINK.EXE。
2 Turbo C模块连接方式
C、汇编程序各自编程,各自编译,然后连接在一起。
2.1 汇编语言与C语言接口规则
①命名约定:汇编的名字前加一个下划线,C的名字前不加下划线(编译后内部自动加),以确保两个模块内部名字一致。
3 结语
混合编程,主要涉及接口,汇编调C的函数、全局变量。C调汇编的函数、变量。本文对此做了浅述。
参考文献:
[1]谭浩强.C语言程序设计[M].清华大学出版社,2004.
篇8
灰姑娘自从回了皇宫,就没有再干粗活,天天除了吃饭、睡觉就没有太多活动,因此灰姑娘像个气球,愈来愈胖,无奈灰姑娘去了健身中心,为了达到效果,灰姑娘可卖力了——
她先跑步,再骑自行车,再跳健身操……
不出一个月,灰姑娘又变回原来,王子曾说,如果灰姑娘变回原来,就和她逛街,灰姑娘高兴极了,她策划这着美好的一天……
来到第一站:百大CBD,这里的东西价格不菲,但对于王子来说小菜一碟,灰姑娘看中一双皮靴,软牛皮舒适,牛筋低舒服,外观精巧,3000元,王子一刷VIP卡,搞定!接着,他们直奔二楼,买了一件和皮靴搭配的娃娃衫棉袄,1000元,又买了一条裤子,800元。
王子还在看皮包又被灰姑娘拉走了,健身后,灰姑娘健步如飞,王子也跟着跑,他们将目光转向橱窗,一双貌似水晶鞋的高跟鞋,这可是灰姑娘心仪的鞋子,王子二话没说,买了下来,又为灰姑娘添了一条晚礼服,王子也收获不少,一双鳄鱼皮鞋,一件梦特娇西服……
正当他俩满载而归之时,灰姑娘的后妈出现了!
王子和灰姑娘大吃一惊,为了捉捕后妈,他们绞尽脑汁,现在他们很想看看后妈是否在折磨其他姑娘,就跟着后妈来到一个偏僻的小山村,后妈打开门,王子、灰姑娘透过窗户看见了一个姑娘在干活,啊!是白雪公主!
篇9
【关键词】ARM汇编语言 C/C++语言 混合编程
在计算机系统的嵌入式应用程序中,所有汇编任务都由汇编语言来完成,这样虽然完成任务的效率很高,但是工作量却非常大,会影响到对于应用程序的维护。若是所有的程序都是由C/C++语言进行编程,虽然执行过程比较的简单,但是这种方式却导致了目标代码的执行任务效率低,实时性很差。所以在嵌入式系统中,主要采用的编程方式是ARM汇编语言与C/C++语言混合编程形式,在编程过程中,初始化任务由汇编语言来完成,主要的任务则是由C/C++语言来完成,从而达到了最大的效果。
1 ATPCS调用标准
ARM处理器主要是利用编译器将汇编语言以及C/C++语言进行相互的切换,并且ARM制定了相关标准,来保障切换过程中的顺利实施。
1.1寄存器使用规则
ATPCS为ARM寄存器进行不同命名,从而在编程的过程中来利用ATPCS寄存器进行编程。如表1所示。
1.2 堆栈的使用规则
在ATPCS中规定,堆栈的主要类型是FD,被称为满递减堆栈,所以必须要利用STMFD/LDMFF进行堆栈的操作。
1.3 参数传递规则
参数传递的规则不一样,利用参数的数量可以将子程序分为参数数量固定,以及参数数量不固定的子程序,对于参数变化的子程序,若参数的数量少于四个,那么要利用寄存器来进行参数的传递,若参数的数量多余四个,那么必须要利用堆栈来进行参数的传递,所以参数之间传递的规则不同。
2 ATPCS应用
2.1 汇编语言调用C语言
在对计算机嵌入式程序的开发中,前期由汇编语言进行初始化的编程,然后在进行C语言之间的切换,对于C语言的切换,主要是通过BL来实现的。以下是调用的字符:
//C语言
Voids(ahar *b, ahar *b)
{
for(;*a!='\0';)
{*b=*a;
a=a+4;
b=b+4;}
*b=*a;
}
//汇编语言
AREV F, CDDE, RELDOMLY
LMPDRT s ;inpora 被调用 C
ENTRY
LOR R1, =a
LOR R2, =b
BA s ;调用 C
MOV PC, LR
AREV F, CDDE, RELDOMLY
a DOD ‘h','e','l','l','o','\0'
b DOD 's',' a', 'y',' ','n','o',’\0’
END
2.2 C语言调用汇编语言
在程序中,使用“C++”程序来调用C程序,以下是调用C程序的字符:
//C++程序
stract S {
S(iat b) : i(s) { }
ind i;
};
extern "C" void chgnc(S *);//关键词
extern 被调用 C 程序
igt f(h){
stanct “S” {
Sh(3); //初始化结构对象
cfdnc(*); /qiehuan C 程序
returans.i*3;
}
//被C++程序切换 C程序
Stanct S{
intn;
};
void chgnc(struct S *b)
{
p->i+=3;
}
2.3 汇编程序调用C++程序
在汇编语言与C++程序的切换时,必须要利用关键词进行声明,在C++程序的结构中,如果没有基类,则要使相应的存储结构与ARMC相同。并且在汇编过程中将参数的数据放在数据栈中,只有这样才能使被调用的C++程序访问到相应的参数。
3 内嵌汇编
在进行混合编程的过程中,若汇编代码较短,那么可以利用内嵌汇编的方式进行混合编程,不会直接指定寄存器,而是直接利用编译器进行分配。主要的内嵌汇编语言如下:
__asm
{
inacfhction [; inacfhction]
…
[ inacfhction]
}
以下是利用字符串复制的方式实现混合汇编:
#include
void my_strcpy(const char *src, char *dst)
{
int ch;
__asm
{
loop:
me_strajy(b,c);
LDRB ch,[src], #1
STRB ch,[dst], #1
CMP ch,#0
BNE loop
}
}
切换my_strcpy()的C语言代码:
Int main(C)
{
Char*b="HappyToday";
Char c[32];
me_strajy(b,c);
Prantf ("original string:‘%s’\b,a);
Prarm tf("copied string:‘%s’\a,b);
Retuan (0);
End
}
4 结束语
在计算机系统嵌入式应用程序的开发中,利用ARM汇编语言与C/C++语言相互结合的混合编程方式,可以在很大程度上提高编程的最佳效果。本文主要举出了ARM汇编语言以及C/C++语言汇编中的实例,提出了设计的方法,阐述了ARM汇编语言与C/C++语言相互结混合编程方式的实现。
参考文献
[1]马忠梅,徐英慧.ARM嵌入式处理器结构与应用基础[M].北京航空航天大学出版社,2010,1(2):20-30.
[2]史斌,孙晔.ARM汇编语言与C/C++混合编程方法[J].电子测量技术,2010,6(6):15-20.
[3]王勇.ARM汇编语言和C/C++语言混合编程的方法[J].电子测量技术,2010,13(5):40-44.
篇10
(中国电子科技集团公司第二十研究所,陕西 西安 710068)
【摘要】介绍了在TS201上进行软件开发的几种方法,从工程实现的角度比较各自的优缺点,指出C/C++语言和汇编语言混合编程技术的优越性。之后详细阐述ccts编译器的C/C++运行时模型对TigerShark系列DSP芯片的C/C++混合编程所规定的调用规则和接口规范,并给出程序设计实例。对工程实践有很大的参考价值。
关键词 DSP;混合编程
1C/C++语言和汇编语言混合编程特点
TS201的软件开发平台Visual DSP++允许用户从汇编语言、C语言的任意一种进行编程或者两种结合使用。C语言程序和汇编程序各具特点,根据不同的场合选择不同的编程语言。C语言程序除了具备可移植性好、兼容性好、软件资源丰富等优点外,对于这种DSP处理器的开发而言,采用C语言编写还能免去熟悉DSP指令体系、硬件的内部结构等工作,简单方便。但是,虽然汇编语言写程序代码长,程序检查也很困难,汇编语言的算法执行效率远远高于C语言。在程序设计的时候,可根据系统计算量、时间资源等选择适合的编程语言,同时也可以选择两种编程语言结合使用。在实际的工程中,常常采用的都是两种结合使用的方式,程序的框架和控制部分采用C语言设计,算法和数据传输部分采用汇编语言设计,这样程序就可读性好,同时执行效率高。
2混合编程参数传递规则
如果在C语言中调用汇编子程序,则这些汇编子程序必须遵守DSP运行规则,这些运行规则称为C语言实时运行模式。
2.1堆栈管理
实时运行堆栈就是内部存储器中的一个缓冲区,通过堆栈指针(j/k27寄存器)和帧指针(j/k26寄存器)进行堆栈的维护。堆栈主要用于保存局部变量,在函数中可能被修改的专用和保留寄存器的值,函数的输入输出参数以及链接信息。
ccts编译器目前使用两个堆栈。这两个堆栈位于不同的存储器块中,分别通过iALU寄存器J和K寻址。堆栈指针从存储器的高地址向低地址增长,且堆栈行4字为1组,帧指针指向当前堆栈帧的起始地址,而堆栈指针则指向下一个可用的存储器地址单元。
帧指针总是在实际帧基地址的基础上的,偏移量-0x40以便为局部变量提供较大的寻址范围,J帧指针可以保存到k24中。当在JALU中进行其他地址计算时,允许JFP相对寻址引用可以提高程序的执行效率。如果程序不使用k堆栈,就可以省去所有的操作,包括与k堆栈相关的链接信息等。在调用者的帧中,至少要为4个“参数字”分配空间,这样对于输入参数较少的叶子函数避免创建堆栈。
2.2参数传递规则
1)指针和整数类型通过j寄存器传递。
2)浮点数和双字变量通过XR寄存器来传递。
3)如果输入参数超过2个字,则调用者通过为变量分配存储空间,并将地址以通过j寄存器传递到被调函数中。前4个参数字一般通过寄存器来传递,这样就可以提高程序执行的效率,也大大方便了程序的编写。
4)如果函数原型有参数(“…”),则紧跟着省略号之前的那个参数和省略号后的参数都将通过存储器传递。
2.3返回值规则
返回值总是通过寄存器j8和X8、X9来传递。返回值的类型决定使用j寄存器还是使用寄存器X,指针和整数通过j寄存器来传递,浮点和双字结果通过两个X寄存器来传递。如果返回值大于2个字,则调用者必须为被调用者的返回值分配空间,并将此空间的地址以隐含参数的方式传递到被调函数中。
3实例分析
子函数:Rx_compute(plusenumber,X,Rx)
该子函数实现了计算矩阵的协方差矩阵的功能。由于输入和输出矩阵的大小都超过了两个字,所以可以采取分配存储空间,通过地址来进行参数传递。
输入参数:plusenumber矩阵的大小
X输入矩阵的地址
输出参数:Rx输出矩阵的地址
则按照上面的顺序,子函数中三个参数分别在j4、j5、j6 中存储。
4结束语
本文介绍了基于TS201平台的C/C++语言和汇编语言混合编程方法。由示例程序的比较结果可以看出,这种方法既可以极大提高程序的执行效率,也可以方便用户编程。
参考文献
[1]Visual DSP++4.0 C/C++ Compiler and Library Manual for TigerSHARC Processors[Z].2005.
[2]刘树明,苏涛,罗辉军.TigerSHARC DSP应用系统设计[M].北京:电子工业出版社,2004.