Linux下的扬声器汇编程序设计

来源 :电子与电脑 | 被引量 : 0次 | 上传用户:tfnpfije
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  Linux是目前最常用的操作系统之一,同微软的Windows系列操作系统相比,它具有速度快、安全性、稳定性好、源代码开放且免费等优点。我国Linux的发展也处于蓬勃发展的局面,据权威预测,中国Linux人才的需求将突破120万。对于大多数只熟悉DOS/Windows程序设计的国内程序员来说,了解和掌握Linux下的程序设计大有裨益。这里介绍在Linux 下进行扬声器汇编程序设计。
  
  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 系统终端窗口中输入可执行文件名即可。运行我们的扬声器的示例程序,可以输入如下命令:
  [root@sunqd]$ ./speaker
  需要注意的是,扬声器程序需要访问计算机系统的I/O端口,所以需要切换为系统管理员(root)权限的用户才能正常运行该程序,否则系统将提示“Segmentation fault”出错信息。
其他文献
随着汽车音频系统越来越复杂,客户需要更加丰富的声音,音频器件必须能够处理更多信道和更高功率。在音频放大应用中,模拟AB类放大是针对应用的常用技术,Class AB放大器也一直广泛应用于音频行业,相比而言,D类放大技术采用了脉宽调制(PWM)技术,可以将功率效率从一般的50%提高到90%以上。这样就可以减少散热,在更小的空间内支持更多声道和更高功率,所以业界慢慢开始向D类放大技术过渡。  但是由于汽
期刊
AnalogicTech推出了业界第一款在一个超小型的3mm×4mm封装内集成了一个500mA电池充电器、250mA降压型转换器和300mA低压差(LDO)线性稳压器的功率管理芯片AAT2554。  所有这3项功能针对那些以一块单片锂电池为电源的超低功率的应用进行了优化。电池充电器工作的输入电压范围是4V ~ 6.5V,而降压转换器和低压差线性稳压器(LDO)工作的输入电压范围是2.7V~5.5V
期刊
无线网络技术的进步,使得移动上网由名词变成了动词,而Web 2.0议题开启一股新兴的软件革命,这两波同时兴起的新风潮将使Mobile Web Services成为Web 2.0众技术之一,本文将从移动端的观点简要介绍Web 2.0及Mobile Web Services技术。    Web 2.0    近来随意翻阅信息类、甚或是管理类的杂志,多少可读到Web 2.0相关介绍。无疑地,Web 2.
期刊
Atmel宣布推出驱动集成电路 ATA6826,这是市面上首个采用高电压 BCD-SOI 技术 (SMARTIS) 的产品。新的驱动集成电路的性能有所改善,具有众多保护功能且价格极具吸引力。ATA6826 的设计目的是,在汽车应用中通过1个微控制器控制2个直流电机或3个不同负载。这些汽车应用包括车镜位置控制及汽车环境控制等车身电子系统。该设备具有高达40V的高电压能力,因此,ATA6826 也适用
期刊
随着LCD技术日趋成熟,消费者对于画质的要求也越来越苛刻。现在,LCD的平均亮度都达到了250流明以上,可视角度也达到了160°/160°的宽视角,而当响应时间提速至全程8ms响应时间后,几大关键性技术难关都已经得到了有效解决。相比而言,仅次于亮度的另一大重要指标——对比度,在提升LCD显示画质方面的重要性正日益突显。  2006年7月5日,LG在主题为“清晰至真 锐比无限”新品发布会上,正式对外
期刊
LSI推出支持8GFC与全磁盘加密的旗舰存储系统    LSI公司日前宣布推出增强型Engenio 7900存储系统,其可为中端存储区域网络(SAN)客户提供“面向未来”的存储基础架构,旨在满足不断增长的数据与不断发展的应用、配置及容量需求。  新型LSI Engenino 7900的特性与功能不仅包括8Gb/s光纤通道(8GFC)接口,可使服务器与存储系统之间每通道带宽提高一倍;同时还具有按需购
期刊
泰科电子旗下的瑞侃电路保护部宣布推出了PolyZen聚合物增强型齐纳二极管微型集成模块。PolyZen器件设计用于满足采用圆桶型插口作为直流电源输入的便携设备的过电流和过电压保护要求,有助于保护敏感型电子设备,避免由于感应电压尖峰、电压瞬变、不正确电源和极性接反所导致的损坏现象。  新型PolyZen器件提供了联合保护功能,一方面具有诸如齐纳二极管的保护能力,另一方面能够耐受高功率故障。PolyZ
期刊
Altera亚太区副总裁兼董事总经理Erhaan Shaikh先生将介绍Altera 40nm FPGA和ASIC的推出对整个FPGA和ASIC产业的重要意义及对Altera高阶市场的重要意义。    Q1:您觉得与2007年相比,2008年贵公司及整个产业有什么改变吗?    Shaikh先生:与去年相比,Altera今年的策略并没有太多改变,我们继续在各种应用上给客户提供有价值的解决方案,继续
期刊
SiGe 半导体公司宣布推出全球首款配合伽利略卫星 (Galileo) 的接收器,适用于一般消费电子产品,可将高精度导航服务集成到笔记本电脑、PDA、媒体播放器、手机以及照相机等便携式设备中。  SE4120 让消费电子产品制造商甚至可以在标准获得定案之前,就设计和开发出配合伽利略系统的产品,以抢占这一市场先机。由于这款接收器架构乃基于软件,因此只需通过简单的软件升级便能够支持标准的更改。这样,制
期刊
半导体市场今后将继续呈成长之势。尽管我们预计近期谨慎之风将占主导地位,但是,那些希望在各自的市场中保持领先地位的公司必需不断地创新,专注于开发在效能上有别于竞争对手的系统级产品,并使用最先进、最尖端的组件。    Q1:贵公司(您)对2009年所属产业的景气是持何种态度?理由是什么?    原因:当前的宏观经济环境,对全球来说颇具挑战性,因为经济发展必需应对信贷紧缩和全球性的市场低迷。虽然各家公司
期刊