由于学习和实验的需要,用U盘烧的ScientificLinux6.7(x86_64)做大白菜u盘启动盘盘,启

RPM Scientific Linux 6 bcel 5.2 x86_64 rpm
bcel rpm build for : Scientific&Linux&6. For other distributions click .
Name : bcel
Version : 5.2
Release : 7.2.el6
Source RPM :
Summary : Byte Code Engineering Library
Description :
The Byte Code Engineering Library (formerly known as JavaClass) isintended to give users a convenient possibility to analyze, create, andmanipulate (binary) Java class files (those ending with .class). Classesare represented by objects which contain all the symbolic information ofthe given class: methods, fields and byte code instructions, inparticular.
Such objects can be read from an existing file, betransformed by a program (e.g. a class loader at run-time) and dumped toa file again. An even more interesting application is the creation ofclasses from scratch at run-time. The Byte Code Engineering Library(BCEL) may be also useful if you want to learn about the Java VirtualMachine (JVM) and the format of Java .class files.
BCEL is alreadybeing used successfully in several projects such as compilers,optimizers, obsfuscators and analysis tools, the most popular probablybeing the Xalan XSLT processor at Apache.
RPM found in directory: /mirror/ftp.scientificlinux.org/linux/scientific/6.4/x86_64/os/Packages
mirror.switch.ch&
mirror.switch.ch&
mirror.switch.ch&
mirror.switch.ch&
mirror.switch.ch&
mirror.switch.ch&
ftp.gwdg.de&
ftp.gwdg.de&
ftp.gwdg.de&
ftp.gwdg.de&
ftp.gwdg.de&
ftp.gwdg.de&
ftp.gwdg.de&
ftp.gwdg.de&
ftp.rediris.es&
ftp.rediris.es&
ftp.rediris.es&
ftp.rediris.es&
ftp.rediris.es&
ftp.rediris.es&
ftp.pbone.net&
ftp.icm.edu.pl&
ftp.pbone.net&
ftp.icm.edu.pl&
ftp.icm.edu.pl&
ftp.pbone.net&
ftp.icm.edu.pl&
ftp.icm.edu.pl&
ftp.pbone.net&
ftp.icm.edu.pl&
ftp.pbone.net&
ftp.icm.edu.pl&
ftp.pbone.net&
ftp.pbone.net&
ftp.pbone.net&
ftp.icm.edu.pl&
ftp.pbone.net&
ftp.icm.edu.pl&
&&&&&Provides :bcel-5.2.jar.so()(64bit)bcelbcel(x86-64)Requires :
Content of RPM :/etc/maven/fragments
/etc/maven/fragments/bcel
/usr/lib64/gcj/bcel
/usr/lib64/gcj/bcel/bcel-5.2.jar.db
/usr/lib64/gcj/bcel/bcel-5.2.jar.so
/usr/share/doc/bcel-5.2
/usr/share/doc/bcel-5.2/LICENSE.txt
/usr/share/doc/bcel-5.2/changes.html
/usr/share/doc/bcel-5.2/classfile.mdl
/usr/share/doc/bcel-5.2/contributors.html
/usr/share/doc/bcel-5.2/eps
/usr/share/doc/bcel-5.2/eps/classfile.fig
/usr/share/doc/bcel-5.2/eps/classgen.fig
/usr/share/doc/bcel-5.2/eps/classloader.fig
/usr/share/doc/bcel-5.2/eps/constantpool.fig
/usr/share/doc/bcel-5.2/eps/diagram.fig
/usr/share/doc/bcel-5.2/eps/il.fig
/usr/share/doc/bcel-5.2/eps/instructions.fig
/usr/share/doc/bcel-5.2/eps/javaclass.fig
/usr/share/doc/bcel-5.2/eps/jvm.fig
/usr/share/doc/bcel-5.2/faq.html
/usr/share/doc/bcel-5.2/generic.mdl
/usr/share/doc/bcel-5.2/images
/usr/share/doc/bcel-5.2/images/bcel-logo.gif
/usr/share/doc/bcel-5.2/images/classfile.gif
/usr/share/doc/bcel-5.2/images/classgen.gif
/usr/share/doc/bcel-5.2/images/classloader.gif
/usr/share/doc/bcel-5.2/images/constantpool.gif
/usr/share/doc/bcel-5.2/images/il.gif
/usr/share/doc/bcel-5.2/images/instructions.gif二次元同好交流新大陆
扫码下载App
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
生命不息,奋斗不止!!!做一个自尊自爱自强的人。
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
安装qt的过程在不同的平台上会有所不同,主要关嵌入式linux平台上如何安装。若需要提供对OpenSSL的支持,需要通过单独安装OpenSSL Toolkit,来获得Secure Sockets Layer (SSL)。对于不同的平台上,会有不同的要求。下面具体关注嵌入式linux的要求。如果要在qt上对QtWebKit模块的支持,必须使用uClibc 0.9.29或者更高的版本,以对pthread的支持。在内存方面的要求主要取决于体系架构以及在编译过程中使能的QT选项。下面是针不同平台上qt支持库的大小。
Architecture&&&&&&
linux-x86-g++
linux-arm-g++
linux-arm-g++ (thumb)
linux-mips-g++ (MIPS32)
2 qt-embedded-linux的安装
(1)下载源码包,解压;
&&&&&& 下载开源嵌入式版本的网址:/qt/source/常用官网
qt news:/about/news
qt downloads:/downloads
qt Quarterly:/qq/
qt bugs:/developer/task-tracker
qt Supported Platforms:/supported-platforms.html
qt Version Changes :/developer/changes
qt books: /developer/books&&&
(2)建立支持库
&&&&&& 通过./configure来设置,主要配置可以通过--help来获得帮助;之后用make命令,然后用make install 命令。将库安装到指定的路径下面。其中的设置包括指定安装的路径;未配置的话,默认的路径是/usr/local/Trolltech/QtEmbedded-4.5.0;
(3)设置环境变量
&&&&&& 为了能够使用Qt for Embedded Linux,& 必须导出的PATH变量有qmake, moc 以及其他Qt for Embedded Linux 的工具, 以及LD_LIBRARY_PATH 必须导出。例如:&&& PATH=/usr/local/Trolltech/QtEmbedded-4.5.0/bin:$PATH
&&&&& export PATH
(4)建立虚拟的frambuffer。
&&&&&& 建立虚拟的frambuffer,需要安装X11 Platforms .
& 3 嵌入式linux版本的qt环境变量
POINTERCAL_FILE:指定文件包含的数据,用来校准触摸笔设备。同时可以参考QWSCalibratedMouseHandler and Qt for Embedded Linux Pointer Handling.
QT_ONSCREEN_PAINT:如果定义了的话,可以用来将控件显示在屏幕上。如果没有其他控件在同一个区域的话,该设备响应的区域将不会随着屏幕设备驱动的改变而改变。设置这个环境变量相当于在控件中应用程序中设置Qt::WA_PaintOnScreen。
QWS_SW_CURSOR:如果定义了的话,软件鼠标的光标将一直是可用的。(即使使用硬件加速驱动器来支持硬件光标)
QWS_DISPLAY:指定显示形式和framebuffer.例如:export QWS_DISPLAY=&driver&[:&driver specific options&]...[:&display num&]
QWS_SIZE:指定嵌入式linux qt窗口在屏幕上的大小。export QWS_SIZE=&width&x&height&
QWS_MOUSE_PROTO:指定触摸设备。 export QWS_MOUSE_PROTO=&driver&[:&driver specific options&],&driver&参数可以是MouseMan, IntelliMouse, Microsoft, VR41xx, LinuxTP, Yopy. Tslib and keys。/dev/mouse 指的是鼠标设备,& /dev/ts for touch panels。
QWS_KEYBOARD为输入设备指定输入设备和驱动。比如:export QWS_KEYBOARD=&driver&[:&driver specific options&]。&driver&参数可以是SL5000, Yopy, VR41xx, TTY, USB and keys,指定的是一个标准设备。比如:/dev/tty0。4 在嵌入式linux上运行qt程序
任何嵌入式linux应用程序可以通过构建QApplication 对象QApplication::GuiServer的格式,被构建为服务server application。或者通过-qws命令行选项的方式。本文当假设用The Virtual Framebuffer 或者嵌入式linux的VNC协议,或者正确配置的Linux framebuffer。而且没有服务进程在运行。可以使用的显示方式有:
&&& &Using a Single Display
&&& 单显示,运行这种显示方式,改变Linux console,而且选择一个应用来运行。它要求在安装过程中,环境变量是可用的。它要求指定的硬件设备驱动必须工作正常。比如:
&&& cd path/to/QtEmbedded/demos/textedit
&&& ./textedit -qws
&&& * Using Multiple Displays
&&& linux同时也是支持多设备显示。有两种方式可以完成。当在运行多服务程序的时候,显示屏的驱动(以及数量)必须为每一个程序进行指定。用-display命令行或者QWS_DISPLAY 来指定。比如:
&&& ./myfirstserverapplication -qws -display "transformed:rot90:1"
&&& ./mysecondserverapplication -qws -display "QVFb:2"
需要注意的是,必须指定一个显示设备,在开始客户端程序的时候。比如:./myclientapplication -display "QVFb:2"。在程序运行的时候,没有办法将一个客户端程序从一个显示移动到另一个显示。用多显示屏驱动,另一方面,应用程序可以方便的在两个不同类型的显示屏之间切换。多屏幕显示可以用-display命令行参数来指定 或者通过设置QWS_DISPLAY环境变量比如: ./myserverapplication -qws -display "Multi: QVFb:0&& QVFb:1:offset=0,0 VNC:offset=640,0 :2"
&&& * Command Line Options
&&& 命令行选项5 移植qt在嵌入式linux的应用
&&& 移植过程和移植到x11平台上的差别不大,遵守通用的移植过程。然后还包括几个方面:字体库移植,设置环境变量以及Framebuffer的支持。
&& 字体库的支持:是在qt的/lib/fonts目录下。由于程序运行的时候是到这个文件夹下面来调用,因此需要将字体库复制到这个目录下。
&& 环境变量的设置:通常情况下,与默认的环境变量不同,因此需要设置的有QWS_MOUSE_PROTO, QWS_KEYBOARD 以及 QWS_DISPLAY,用来指定鼠标、键盘以及显示设备管理。在./configure 的时候需要加入的选项是-qt-kbd-&keyboarddriver& and -qt-mouse-&mousedriver& ,这样才能使能这些设备驱动。但是还需要指定一个具体的设备,因此需要通过设置环境变量来完成。
&& framebuffer的支持:没有特殊需求的情况下,要求在目标设备上使能framebuffer。Linux framebuffer在标准设置情况下是使能的。6 嵌入式linuxqt 显示管理
当需要显示的时候,默认的动作是每一个嵌入式linux的客户端将 需要的显示的色调存放在内存中,然后服务端将相关的数据从内存在中送到显示屏上。服务端用显示屏驱动copy内存中的内容到显示屏上显示。显示屏的驱动是在服务端应用加载的时候运行的,用的是qt的插件系统。常用的方式有:可用的驱动;指定一个驱动;子驱动和多驱动。
嵌入式linux的qt提供的驱动有Linux framebuffer, the virtual framebuffer, transformed screens, VNC servers and multi screens.通过运行./configure 选项来列出可用的驱动。默认的配置是不加速的Linux framebuffer driver (/dev/fb0) 被打开。其他的设备驱动也可以使能或者禁止,通过以下命令行。例如:./configure -qt-gfx-transformed
&& 通过设置环境变量QWS_DISPLAY来指定一个设备。比如:格式如下的: export QWS_DISPLAY="&driver&[:&driver specific options&]... [:&display num&]"& &driver&可以用的参数有:LinuxFb, QVFb, VNC, Transformed, Multi and keys identifying custom drivers。参数&display num&的被用来分辨用相同驱动的屏幕,而且使能多显示。如下的表格用来指定驱动。环境变量的QWS_DISPLAY也可以通过-display来设置。比如: myApplication -display "&driver&[:&driver specific options&]...& [:&display num&]"
&&& Subdrivers and Multiple Drivers子驱动和多驱动
&&& VNC, Transformed 和Multi screen drivers取决于子驱动。通用的语法是: export QWS_DISPLAY="&driver&[:&subdriver&][:&subdriver options&]...[ :&display num&]"至于子驱动,在每个子驱动之间加上空间是很重要的,在显示设备前加上用来分开各个驱动和显示设备。注意的是多屏幕驱动可以拥有多个子设备驱动,比如: export QWS_DISPLAY="Multi: QVFb:0 QVFb:offset=640,0:1 :2"注意的是:VNC screen driver在没有指定屏幕驱动的情况下,默认的是虚拟屏幕驱动。在这种情况下,VNC driver有一些额外的参数来指定大小的位宽,参数有:&&& * size=&width x height&& * depth=&value&&& * mmHeight=&physical height in millimeters&
* mmWidth=&physical width in millimeters& 。例如:export QWS_DISPLAY="VNC:size=720x480:depth=32"。例如运行VNC屏幕驱动在Linux framebuffer driver的情况下,则:export QWS_DISPLAY="VNC:LinuxFb"7 输入设备键盘和鼠标的设置与管理
&&&&&& 当运行一个Qt for Embedded Linux应用程序的时候,不管是作为一个服务还是连接到另一个服务,当它开始运行的时候,鼠标驱动被服务的应用加载,用qt的plugin system。 在配置qt的时候通过选项来选择支持的鼠标以及键盘设备,同时测试可用的设备。通过 ./configure -help 查看可用的设备,配置时候默认的是PC的鼠标驱动。如果是自己添加一个设备,比如触摸屏,则需要创建一个QWSCalibratedMouseHandler subclass来完成校验功能。若提供的pc的鼠标被使能,Qt for Embedded Linux将会自动探测所支持的一种鼠标设备,这个设备是在/dev/psaux 或者 /dev/ttyS的一种。如果多种类型的都检测到的话,则多种同时支持。需要注意的是,Qt for Embedded Linux 不支持自动检测触摸屏设备,因此需要指定使用的是哪一种。要设置环境变量QWS_MOUSE_PROTO ,例如:export QWS_MOUSE_PROTO=&driver&[:&driver specific options&],其中的参数&driver&可以是MouseMan, IntelliMouse, Microsoft, VR41xx, LinuxTP, Yopy, Tslib and keys,driver specific options是一个标准设备,比如:dev/mouse,触摸屏的是/dev/ts。多鼠标可以用下列方式来指定。
&export QWS_MOUSE_PROTO="&driver&[:&driver specific options&]
&&&&&&&& &driver&[:&driver specific options&]
&&&&&&&& &driver&[:&driver specific options&]"
需要注意的是:Vr41xx 驱动有两个可选的参数:press=&value&来定义单击的时间(默认值是750);filter=&value& 指定的是滤波长度。用于虑掉噪声。比如:
&&&&&&& export QWS_MOUSE_PROTO="Vr41xx:press=500:/dev/misc/ts"
对于The Tslib Mouse Driver是一个继承QWSCalibratedMouseHandler的类,在产生鼠标事件的时候,提供校验和滤波的功能,用于使用同一的触摸屏的库。为了使用鼠标,必须编译的选项是-qt-mouse-tslib。此外,tslib的头文件和库也要在build的环境变量中指出来。tslib 的源码可以在http://tslib.berlios.de. 下载。通过-L 和-I 来指定库和头文件的位置。比如: ./configure& -L &path to tslib library& -I &path to tslib headers&。 为了保证能够使用鼠标,tslib必须正确的安装在目标机上。包括提供一个ts.conf 配置文件和设置必要的环境变量。ts.conf包括两行:内容是: module_raw input
&&&&& module linear在make Qt for Embedded Linux 时候特别指定tslib 鼠句柄,设置环境变量QWS_MOUSE_PROTO 。可能出现问题的地方是设备文件和文件权限两个方面。为了保证能够正确的使用设备文件,第一步,先测试一下设备文件是否有输出。比如:如果指定的鼠标设备驱动是:QWS_MOUSE_PROTO=IntelliMouse:/dev/input/mouse0,然后检查设备的输出,通过在控制台上敲: cat /dev/input/mouse0 | hexdump,移动鼠标后,如果可以在控制台上看见输出,表示能够正确的使用设备,否则要重新连接设备。对于设备的读写权限,一般要求对设备至少有读权限。比如:QWS_MOUSE_PROTO=IntelliMouse:/dev/input/mouse0,那么应该将该设备的权限设置为chmod a+rw /dev/input/mouse0。如果设备文件符号连接到另一个文件的话,必须改变相关文件的属性。
&&& 呵呵,好舒服,今天下午的心情是最激动地,当我看到显示器的画面和鼠标的移动,嘿嘿!着可是我辛苦一个多月的成果呀,呵呵!从制作grub,制作根文件系统,移植qt ,可谓是一路走来,风尘仆仆的走来呀,嘿嘿!
&&& 仔细想想,正是开工还是在一个半月以前,当时想的是用虚拟机来启动,然后拿到了研华工控机,很爽。做grub,从u盘引导,制作linux根文件系统,定制linux 内核,调整驱动模块,制作initrd.img文件,移植qt-embedded for linux,可真多。想想,还挺有意思。由此可见,当我看到鼠标可以移动,键盘驱动都做好的时候,呵呵,那个舒服呀。后面的工作就是要把这些过程完整的记录下来,包括遇见的问题以及具体的处理方法,解决问题的思路。在这里,我要好好感谢一下小金、智哥等等几个哥们对我的支持,看看,都快把人家的书用破了,嘿嘿。
&&& 具体的解决方法,都会在技术板块做出详细记录。嘿嘿!&
&&& 所以呢,今天早早就回家,给自己放点小假,出去跑跑步,好好锻炼身体,哈哈!
&& 当系统上电之后,需要一段程序来进行初始化:关闭WATCHDOG、改变系统时钟、初始化存储控制器、将更多的代码复制到内存中等等。如果它能将操作系统内核(无论从本地,比如Flash;还是从远端,比如通过网络)复制到内存中运行,就称这段程序为Bootloader。 简单地说,Bootloader就是这么一小段程序,它在系统上电时开始执行,初始化硬件设备、准备好软件环境,最后调用操作系统内核。 可以增强Bootloader的功能,比如增加网络功能、从PC上通过串口或网络下载文件、烧写文件、将Flash上压缩的文件解压后再运行等──这就是一个功能更为强大的Bootloader,也称为Monitor。实际上,在最终产品中用户并不需要这些功能,它们只是为了方便开发。 Bootloader的实现严重依赖于具体硬件,在嵌入式系统中硬件配置千差万别,即使是相同的CPU,它的外设(比如Flash)也可能不同,所以不可能有一个Bootloader支持所有的CPU、所有的电路板。即使是支持CPU架构比较多的U-Boot,需要进行一些移植。
&& CPU上电后,会从某个地址开始执行。比如MIPS结构的CPU会从0xBFC00000取第一条指令,而ARM结构的CPU则从地址0x0000000开始。嵌入式单板中,需要把存储器件ROM或Flash等映射到这个地址,Bootloader就存放在这个地址开始处,这样一上电就可以执行。
&&& 在开发时,通常需要使用各种命令操作Bootloader,一般通过串口来连接PC和开发板,可以在串口上输入各种命令、观察运行结果等。这也只是对开发人员才有意义,用户使用产品时是不用接串口来控制Bootloader的。从这个观点来看,Bootloader可以分为两种操作模式(Operation Mode):
(1)启动加载(Boot loading)模式。 上电后,Bootloader从板子上的某个固态存储设备上将操作系统加载到RAM中运行,整个过程并没有用户的介入。产品发布时,Bootloader工作在这种模式下。
(2)下载(Downloading)模式。 在这种模式下,开发人员可以使用各种命令,通过串口连接或网络连接等通信手段从主机(Host)下载文件(比如内核映像、文件系统映像),将它们直接放在内存运行或是烧入Flash类固态存储设备中。 板子与主机间传输文件时,可以使用串口的xmodem/ymodem/zmodem协议,它们使用简单,只是速度比较慢;还可以使用网络通过tftp、nfs协议来传输,这时,主机上要开启tftp、nfs服务;还有其他方法,比如USB等。 像Blob或U-Boot等这样功能强大的Bootloader通常同时支持这两种工作模式,而且允许用户在这两种工作模式之间进行切换。比如,U-Boot在启动时处于正常的启动加载模式,但是它会延时若干秒(这可以设置)等待终端用户按下任意键而将U-Boot切换到下载模式。如果在指定时间内没有用户按键,则U-Boot继续启动Linux内核。 15.1.2 Bootloader的结构和启动过程 。
&&& 嵌入式系统世界已经有各种各样的Bootloader,种类划分也有多种方式。除了按照处理器体系结构不同划分以外,还有功能复杂程度的不同。首先区分一下“Bootloader”和“Monitor”的概念。严格来说,“Bootloader”只是引导设备并且执行主程序的固件;而“Monitor”还提供了更多的命令行接口,可以进行调试、读写内存、烧写Flash、配置环境变量等。“Monitor”在嵌入式系统开发过程中可以提供很好的调试功能,开发完成以后,就完全设置成了一个“Bootloader”。所以,习惯上大家把它们统称为Bootloader。表6.1列出了Linux的开放源码引导程序及其支持的体系结构。表中给出了X86 ARM PowerPC体系结构的常用引导程序,并且注明了每一种引导程序是不是“Monitor”。&
X86的工作站和服务器上一般使用LILO和GRUB。LILO是Linux发行版主流的Bootloader。不过Redhat Linux发行版已经使用了GRUB,GRUB比LILO有更有好的显示界面,使用配置也更加灵活方便。在某些X86嵌入式单板机或者特殊设备上,会采用其他Bootloader,例如:ROLO。这些Bootloader可以取代BIOS的功能,能够从FLASH中直接引导Linux启动。现在ROLO支持的开发板已经并入U-Boot,所以U-Boot也可以支持X86平台。
ARM处理器的芯片商很多,所以每种芯片的开发板都有自己的Bootloader。结果ARM bootloader也变得多种多样。最早有为ARM720处理器的开发板的固件,又有了armboot,StrongARM平台的blob,还有S3C2410处理器开发板上的vivi等。现在armboot已经并入了U-Boot,所以U-Boot也支持ARM/XSCALE平台。U-Boot已经成为ARM平台事实上的标准Bootloader。
(3)PowerPC
PowerPC平台的处理器有标准的Bootloader,就是ppcboot。PPCBOOT在合并armboot等之后,创建了U-Boot,成为各种体系结构开发板的通用引导程序。U-Boot仍然是PowerPC平台的主要Bootloader。
MIPS公司开发的YAMON是标准的Bootloader,也有许多MIPS芯片商为自己的开发板写了Bootloader。现在,U-Boot也已经支持MIPS平台。
SH平台的标准Bootloader是sh-boot。Redboot在这种平台上也很好用。
M68K平台没有标准的Bootloader。Redboot能够支持m68k系列的系统。值得说明的是Redboot,它几乎能够支持所有的体系结构,包括MIPS、SH、M68K等体系结构。Redboot是以eCos为基础,采用GPL许可的开源软件工程。现在由core eCos的开发人员维护,源码下载网站是/snapshots。Redboot的文档也相当完善,有详细的使用手册《RedBoot User’s Guide》。
今天看了中国男篮的比赛,就一个感觉:憋得慌,相当慌!
&&& 在前面的比赛,没有看到姚明的身影,中国队一样打的很好,让人感觉很爽,很有士气,在大姚没有恢复的情况下,打的挺不错的。在我们每个中国球迷看来,赢下这场比赛势在必得。这次看来只能是失误,不能算是失败。我相信中国男篮是亚洲男篮的NO.1。必须的。必须的。中国男篮,加油!
ARM920协处理器及其指令
一、协处理器指令
ARM 微处理器可支持多达 16 个协处理器,用于各种协处理操作,在程序执行的过程中,每个协处理器只执行针对自身的协处理指令,忽略 ARM 处理器和其他协处理器的指令。ARM 的协处理器指令主要用于 ARM 处理器初始化 ARM 协处理器的数据处理操作,以及在ARM 处理器的寄存器和协处理器的寄存器之间传送数据,和在 ARM 协处理器的寄存器和存储器之间传送数据。ARM 协处理器指令包括以下 5 条:
— CDP&& 协处理器数据操作指令
— LDC&& 协处理器数据加载指令
— STC&& 协处理器数据存储指令
—&&&MCR& &ARM 处理器寄存器到协处理器寄存器的数据传送指令
— MRC&& 协处理器寄存器到 ARM 处理器寄存器的数据传送指令 1.1 CDP 指令
CDP 指令的格式为:
CDP{条件} 协处理器编码,协处理器操作码 1,目的寄存器,源寄存器 1,源寄存器 2,协处理器操作码 2。
CDP 指令用于 ARM 处理器通知 ARM 协处理器执行特定的操作,若协处理器不能成功完成特定的操作,则产生未定义指令异常。其中协处理器操作码 1 和协处理器操作码 2 为协处理器将要执行的操作,目的寄存器和源寄存器均为协处理器的寄存器,指令不涉及 ARM 处理器的寄存器和存储器。
指令示例: 1.2LDC 指令
LDC 指令的格式为:
LDC{条件}{L} 协处理器编码,目的寄存器,[源寄存器]
LDC 指令用于将源寄存器所指向的存储器中的字数据传送到目的寄存器中,若协处理器不能成功完成传送操作,则产生未定义指令异常。其中,{L}选项表示指令为长读取操作,如用于双精度数据的传输。
指令示例:
LDC& P3,C4,[R0]&&&&&&& ;将ARM处理器的寄存器R0所指向的存储器中的字数据传送到协处理器P3的寄存器C4中。& 1.3 STC 指令
STC 指令的格式为:
STC{条件}{L} 协处理器编码,源寄存器,[目的寄存器]
STC 指令用于将源寄存器中的字数据传送到目的寄存器所指向的存储器中,若协处理器不能成功完成传送操作,则产生未定义指令异常。其中,{L}选项表示指令为长读取操作,如用于双精度数据的传输。
指令示例:
STC& P3,C4,[R0]&&&&&&& ;将协处理器P3的寄存器C4中的字数据传送到ARM处理器的寄存器
R0所指向的存储器中。& 1.4 MCR 指令
MCR 指令的格式为:
MCR{条件} 协处理器编码,协处理器操作码 1,源寄存器,目的寄存器 1,目的寄存器 2,协处理器操作码 2。
MCR 指令用于将 ARM 处理器寄存器中的数据传送到协处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码 1 和协处理器操作码 2 为协处理器将要执行的操作,源寄存器为 ARM 处理器的寄存器,目的寄存器 1 和目的寄存器 2 均为协处理器的寄存器。
指令示例: 1.5 MRC 指令
MRC 指令的格式为: MRC{条件} 协处理器编码,协处理器操作码 1,目的寄存器,源寄存器 1,源寄存器 2,协处理器操作码 2.MRC 指令用于将协处理器寄存器中的数据传送到 ARM 处理器寄存器中,若协处理器不能成功完成操作,则产生未定义指令异常。其中协处理器操作码 1 和协处理器操作码 2 为协处理器将要执行的操作,目的寄存器为 ARM 处理器的寄存器,源寄存器 1 和源寄存器 2 均为协处理器的寄存器。
指令示例:
MRC& P3,3,R0,C4,C5,6&&& ;该指令将协处理器P3的寄存器中的数据传送到ARM处理器寄存器中。
二、ARM920T协处理器
RAM920T有两个协处理器:cp14和CP15;其中cp14 4调试通信通道协处理器,CP15系统控制协处理器。2.1 CP14调试通信通道协处理器
调试通信通道协处理器DCC(the Debug Communications Channel)提供了两个32bits寄存器用于传送数据,还提供了6bits通信数据控制寄存器控制寄存器中的两个位提供目标和主机调试器之间的同步握手。
此控制寄存器中的两个位提供目标和主机调试器之间的同步握手:
位 1(W 位)& 从目标的角度表示通信数据写入寄存器是否空闲:
W = 0& 目标应用程序可以写入新数据。
W = 1& 主机调试器可以从写入寄存器中扫描出新数据。
位 0(R 位)& 从目标的角度表示通信数据读取寄存器中是否有新数据:
R = 1& 有新数据,目标应用程序可以读取。
R = 0& 主机调试器可以将新数据扫描到读取寄存器中。注意:调试器不能利用协处理器 14 直接访问调试通信通道,因为这对调试器无意义。 但调试器可使用扫描链读写 DCC 寄存器。 DCC 数据和控制寄存器可映射到 EmbeddedICE 逻辑单元中的地址。 若要查看 EmbeddedICE 逻辑寄存器,请参阅您的调试器和调试目标的相关文档。
回读取寄存器的值:
MRC p14, 0, Rd, c1, c0
用于向调试器发送数据的 32 位宽寄存器。 以下指令将 Rn 中的值写到写入寄存器中:MCR p14, 0, Rn, c1, c0。注意:有关访问 ARM10 和 ARM11 内核 DCC 寄存器的信息,请参阅相应的技术参考手册。 ARM9 之后的各处理器中,所用指令、状态位位置以及对状态位的解释都有所不同。&
1.& 目标应用程序检查 DCC 写入寄存器是否空闲可用。 为此,目标应用程序使用 MRC 指令读取调试通信通道控制寄存器,以检查 W 位是否已清除。
2.& 如果 W 位已清除,则通信数据写入寄存器已清空,应用程序对协处理器14 ,使用 MCR 指令将字写入通信数据写入寄存器。写入寄存器操作会自动设置W 位。如果 W 位已设置,则表明调试器尚未清空通信数据写入寄存器。此时,如果应用程序需要发送另一个字,它必须轮询 W 位,直到它已清除。
3.& 调试器通过扫描链 2 轮询通信数据控制寄存器。 如果调试器发现 W 位已设置,则它可以读 DCC 数据寄存器,以读取应用程序发送的信息。 读取数据的进程会自动清除通信数据控制寄存器中的 W 位。
以下代码显示了这一过程
AREA& OutChannel, CODE, READONLY
&&&& ENTRY
&&&& MOV&& r1,#3&&&&&&&&& ; Number of words to send
&&&& ADR&& r2, outdata&&; Address of data to send
&&&& MRC&& p14,0,r0,c0,c0 ; Read control register
&&&& TST&& r0, #2
&&&& BNE&& pollout&&&&&&& ; if W set, register still full
&&&& LDR&& r3,[r2],#4&&&& ; Read word from outdata
&&&&&&&&&&&&&&&&&&&&&&&&& ; into r3 and update the pointer
&&&& MCR&& p14,0,r3,c1,c0 ; Write word from r3
&&&& SUBS& r1,r1,#1&&&&&& ; Update counter
&&&& BNE&& pollout&&&&&&& ; Loop if more words to be written
&&&& MOV&& r0, #0x18&&&&& ; Angel_SWIreason_ReportException
&&&& LDR&& r1, =0x20026&& ; ADP_Stopped_ApplicationExit
&&&& SVC&& 0x123456&&&&&& ; ARM semihosting (formerly SWI)
outdata&&&
&&&& DCB "Hello there!"
(2)调试器到目标的通信
这是运行于主机上的调试器向运行于内核上的应用程序传输消息的事件顺序:
1.& 调试器轮询通信数据控制寄存器的 R 位。 如果 R 位已清除,则通信数据读取寄存器已清空,可将数据写入此寄存器,以供目标应用程序读取。
2.& 调试器通过扫描链 2 将数据扫描到通信数据读取寄存器中。 此操作会自动设置通信数据控制寄存器中的 R 位。
3.& 目标应用程序轮询通信数据控制寄存器中的 R 位。 如果该位已经设置,则通信数据读取寄存器中已经有数据,应用程序可使用 MRC 指令从协处理器14 读取该数据。 同时,读取指令还会清除 R 位。
以下显示的目标应用程序代码演示了这一过程
AREA& InChannel, CODE, READONLY
&&&& ENTRY
&&&& MOV&& r1,#3&&&&&&&&& ; Number of words to read
&&&& LDR&& r2, =indata&&& ; Address to store data read
&&&& MRC&& p14,0,r0,c0,c0 ; Read control register
&&&& TST&& r0, #1
&&&& BEQ&& pollin&&&&&&&& ; If R bit clear then loop
&&&& MRC&& p14,0,r3,c1,c0 ; read word into r3
&&&& STR&& r3,[r2],#4&&&& ; Store to memory and
&&&&&&&&&&&&&&&&&&&&&&&&& ; update pointer
&&&& SUBS& r1,r1,#1&&&&&& ; Update counter
&&&& BNE&& pollin&&&&&&&& ; Loop if more words to read
&&&& MOV&& r0, #0x18&&&&& ; Angel_SWIreason_ReportException
&&&& LDR&& r1, =0x20026&& ; ADP_Stopped_ApplicationExit
&&&& SVC&& 0x123456&&&&&& ; ARM semihosting (formerly SWI)
&&&& AREA& Storage, DATA, READWRITE
&&&& DCB&& "Duffmessage#"
&&&& END2.2 CP15系统控制协处理器
CP15 —系统控制协处理器 (the system control coprocessor)他通过协处理器指令MCR和MRC提供具体的寄存器来配置和控制caches、MMU、保护系统、配置时钟模式(在bootloader时钟初始化用到)
CP15的寄存器只能被MRC和MCR(Move to Coprocessor from ARM Register )指令访问MCR{cond} p15,&Opcode_1&,&Rd&,&CRn&,&CRm&,&Opcode_2&
MRC{cond} p15,&Opcode_1&,&Rd&,&CRn&,&CRm&,&Opcode_2&
-R0:ID号寄存器
-R0:缓存类型寄存器
-R1:控制寄存器
-R2:转换表基址寄存器(Translation Table Base --TTB)
-R3:域访问控制寄存器(Domain access control )
-R5:异常状态寄存器(fault status -FSR)
-R6:异常地址寄存器(fault address -FAR)
-R7:缓存操作寄存器
-R8:TLB操作寄存器
-R9:缓存锁定寄存器
-R10:TLB 锁定寄存器
-R11-12&14:保留
-R13:处理器ID
-R15:测试配置寄存器 2-24&
要注意有2个R0,根据MCR操作数的不同传送不同的值,这也一个只读寄存器
-R0:ID号寄存器 这是一个只读寄存器,返回一个32位的设备ID号,具体功能参考ARM各个系列型号的的CP15 Register 0说明.&
MRC p15, 0, &Rd&, c0, c0, {0, 3-7} ;returns ID&
以下为ID Code详细描叙(ARM926EJ-S); ARM920T Part Number为0x920,Architecture (ARMv4T) 为0x2具体可参照ARM各型号.
MRC p15, 0, &Rd&, c0, c0, 1; returns cache details
以下为CP15的一些应用示例
U32 ARM_CP15_DeviceIDRead(void)
& __asm { MRC P15, 0, id, c0, c0; }
void ARM_CP15_SetPageTableBase(P_U32 TableAddress)
&& __asm { MCR& P15, 0, TableAddress, c2, c0, 0; }
void ARM_CP15_SetDomainAccessControl(U32 flags)
& __asm { MCR& P15, 0, flags, c3, c0, 0; }
void ARM_CP15_ICacheFlush()
& __asm { MCR p15, 0, dummy, c7, c5, 0; }
void ARM_CP15_DCacheFlush()
& __asm { MCR p15, 0, dummy, c7, c6, 0; }
void ARM_CP15_CacheFlush()
& __asm { MCR p15, 0, dummy, c7, c7, 0; }
void ARM_CP15_TLBFlush(void)
& __asm { MCR& P15, 0, dummy, c8, c7, 0; }
void ARM_CP15_ControlRegisterWrite(U32 flags)
& __asm { MCR P15, 0, flags, c1, c0; }
void ARM_CP15_ControlRegisterOR(U32 flag)
&&& mrc p15,0,r0,c1,c0,0
&&& mov r2,flag
&&& orr r0,r2,r0
&&& mcr p15,0,r0,c1,c0,0
void ARM_CP15_ControlRegisterAND(U32 flag)
&&& mrc p15,0,r0,c1,c0,0
&&& mov r2,flag
&&& and r0,r2,r0
&&& mcr p15,0,r0,c1,c0,0
void ARM_MMU_Init(P_U32 TableAddress)
&&&&&& ARM_CP15_TLBFlush();
&&& ARM_CP15_CacheFlush();
&&& ARM_CP15_SetDomainAccessControl(0xFFFFFFFF);
&&& ARM_CP15_SetPageTableBase(TableAddress);
void Enable_MMU (void)
&&& mrc p15,0,r0,c1,c0,0
&&& mov r2, #0x
&&& orr r0,r2,r0
&&& mcr p15,0,r0,c1,c0,0
printf("MMU enabled\n");
void Disable_MMU (void)
&&& mrc p15,0,r0,c1,c0,0
&&& mov r2, #0xFFFFFFFE
&&& and r0,r2,r0
&&& mcr p15,0,r0,c1,c0,0
printf("MMU disabled\n");
常用ARM指令集及汇编
一、 ARM处理器的寻址方式
二、指令集学习
(一) &&& ARM 指令集
1. 指令格式
2. 条件码
3. ARM 存储器访问指令
1) &LDR/ STR -加载 / 存储指令
2) &LDM/ STM -多寄存器加载 / 存储指令
3) &SWP -寄存器和存储器交换指令
4. ARM 数据处理指令
1)&&&&数据传送指令
&&&&&& MOV -数据传送指令
&&&&&& MVN -数据非传送指令
2) &&&&算术逻辑运算指令
&&&&&& ADD -加法运算指令
&&&&&& SUB -减法运算指令
&&&&&& RSB- 逆向减法指令
&&&&&& ADC -带进位加法指令
&&&&&& SBC -带进位减法指令
&&&&&& RSC -带进位逆向减法指令
&&&&&& AND -逻辑“与”
&&&&&& ORR -逻辑“或”
&&&&&& EOR -逻辑“异或”
&&&&&& BIC -位清除指令
3) &&&&比较指令
&&&&&& CMP -比较指令
&&&&&& CMN -负数比较指令
&&&&&& TST -位测试指令
&&&&&& TEQ -相等测试指令
4) &&&&乘法指令
&&&&&& MUL - 32位乘法指令
&&&&&& MLA - 32位乘加指令
&&&&&& UMULL - 64位无符号乘法指令
&&&&&& UMLAL - 64位无符号乘加指令
&&&&&& SMULL - 64位有符号乘法指令
&&&&&& SMLAL - 64位有符号乘加指令
5. ARM 分支指令
&&&&&& B -分支指令
&&&&&& BL -带连接的分支指令
&&&&&& BX -带状态切换的分支指令
6. ARM 协处理器指令
&&&&&& CDP -协处理器数据操作指令
&&&&&& LDC -协处理器数据读取指令
&&&&&& STC -协处理器数据写入指令
&&&&&& MCR - ARM处理器到协处理器的数据传送指令
&&&&&& MRC -协处理器到 ARM处理器的数据传送指令
7. ARM 杂项指令
&&&&&& SWI -软中断指令
&&&&&& MRS -读状态寄存器指令
&&&&&& MSR -写状态寄存器指令
8. ARM 伪指令
&&&&&& ADR -小范围的地址读取伪指令
&&&&&& ADRL -中等范围的地址读取伪指令
&&&&&& LDR -大范围的地址读取伪指令
&&&&&& NOP -空操作伪指令
(二) &Thumb 指令集
1. Thumb 指令集和 ARM指令集的区别
2. Thumb 存储器访问指令
&&&&&& LDR/ STR -加载 / 存储指令
&&&&&& PUSH/ POP -寄存器入栈 / 出栈指令
&&&&&& LDMIA/ STMIA -多寄存器加载 / 存储指令
3. Thumb 数据处理指令
&&&&&& MOV -数据传送指令
&&&&&& MVN -数据非传送指令
&&&&&& NEG -数据取负指令
&&&&&& ADD -加法运算指令
&&&&&& SUB -减法运算指令
&&&&&& ADC -带进位加法指令
&&&&&& SBC -带进位减法指令
&&&&&& MUL -乘法运算指令
&&&&&& AND -逻辑“与”
&&&&&& ORR -逻辑“或”
&&&&&& EOR -逻辑“异或”
&&&&&& BIC -位清除指令
&&&&&& ASR -算术右移指令
&&&&&& LSL -逻辑左移指令
&&&&&& LSR -逻辑右移指令
&&&&&& ROR -循环右移指令
&&&&&& CMP -比较指令
&&&&&& CMN -负数比较指令
&&&&&& TST -位测试指令
&&&&&& B -分支指令
&&&&&& BL -带连接的分支指令
&&&&&& BX -带状态切换的分支指令
5. Thumb 杂项指令
&&&&&& SWI -软中断指令
6. Thumb 伪指令
&&&&&& ADR -小范围的地址读取伪指令
&&&&&& LDR -大范围的地址读取伪指令
&&&&&& NOP -空操作伪指令
ARM处理器共有9中寻址方式
1.寄存器寻址
&& 操作数的值在寄存器中,指令执行时直接取出寄存器的值来操作
&& MOV R1,R2&&& ;R2-&R1
& SUB R0,R1,R2&& ;R1-R2-&R0
2.立即寻址
&&MOV R0,#0XFF00&& ;0XFF00-&R0
& SUBS& R0,R0,#1&&& ;R0-1-&R0
3.寄存器移位寻址
MOV R0,R2,LSL #3&& ;R2的值左移3位,存入R0, R0=R2*8
4.寄存器间接寻址
LDR R1,[R2]
5.基址寻址
LDR R2,[R3,#0XC0]&&& ;读取R3+0XC0地址上的数据,放入R2
6.多寄存器寻址
&LDMIA& R1!,{R2-R7,R12}& ;将R1指向的单元中的数据读出到R2~R7,R12中(R1自动加1)
7. 堆栈寻址
STMFD& SP!,{R1-R7,LR}&& ;将R1-R7,LR入栈,满递减堆栈
8.块拷贝寻址
STMIA R0!,{R1-R7}&& ;将R1-R7的数据保存到R0指向的存储器中。R0自动加1。
9.相对寻址
相对寻址是基址寻址的一种变通。由计数器PC提供基址。指令中的地址码字段作为偏移量。
&&&&&&&&&&&& BL SUB1
&&&&&&&&&&&& BEQ LOOP&&&&&&&&&&
LOOP&& MOV R6,#1
前段时间一直在研究ARM的体系架构,其中有些值得拿出来和大家分享一下,嘿嘿!~这里先说话寄存器R13的用法。&
1、寄存器 R13 在 ARM 指令中常用作堆栈指针
2、对于 R13 寄存器来说,它对应6个不同的物理寄存器,其中的一个是用户模式与系统模式共用,另外5个物理寄存器对应于其他5种不同的运行模式。采用以下的记号来区分不同的物理寄存器: R13_&mode& 其中,mode为以下几种模式之一:usr、fiq、irq、svc、abt、und&
3、寄存器R13在ARM指令中常用作堆栈指针,但这只是一种习惯用法,用户也可使用其他的寄存器作为堆栈指针。而在Thumb指令集中,某些指令强制性的要求使用R13作为堆栈指针。由于处理器的每种运行模式均有自己独立的物理寄存器R13,在用户应用程序的初始化部分,一般都要初始化每种模式下的R13,使其指向该运行模式的栈空间,这样,当程序的运行进入异常模式时,可以将需要保护的寄存器放入R13所指向的堆栈,而当程序从异常模式返回时,则从对应的堆栈中恢复,采用这种方式可以保证异常发生后程序的正常执行。
4、有四种类型的堆栈:堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(Full Stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(Empty Stack)。同时,根据堆栈的生成方式,又可以分为递增堆栈(Ascending Stack)和递减堆栈(DecendingStack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。这样就有四种类型的堆栈工作方式,ARM 微处理器支持这四种类型的堆栈工作方式,即:
◎ Full descending 满递减堆栈堆栈首部是高地址,堆栈向低地址增长。栈指针总是指向堆栈最后一个元素(最后一个元素是最后压入的数据)。 ARM-Thumb过程调用标准和ARM、Thumb C/C++ 编译器总是使用Full descending 类型堆栈。
◎ Full ascending 满递增堆栈堆栈首部是低地址,堆栈向高地址增长。栈指针总是指向堆栈最后一个元素(最后一个元素是最后压入的数据)。
◎ Empty descending 空递减堆栈堆栈首部是低地址,堆栈向高地址增长。栈指针总是指向下一个将要放入数据的空位置。
◎ Empty ascending 空递增堆栈堆栈首部是高地址,堆栈向低地址增长。栈指针总是指向下一个将要放入数据的空位置。
5、操作堆栈的汇编指令堆栈类型 入栈指令 出栈指令 Full descending STMFD (STMDB) LDMFD (LDMIA) Full ascending STMFA (STMIB) LDMFA (LDMDA) Empty descending STMED (STMDA) LDMED (LDMIB) Empty ascending STMEA (STMIA) LDMEA (LDMDB)。
第一部分 Linux下ARM汇编语法尽管在Linux下使用C或C++编写程序很方便,但汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作 ARM的协处理器等。初始化完成后就可以跳转到C代码执行。需要注意的是,GNU的汇编器遵循AT&T的汇编语法,可以从GNU的站点()上下载有关规范。&
一. Linux汇编行结构
任何汇编行都是如下结构:
[:] [} @ comment
[:] [} @ 注释
Linux ARM 汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。
【例1】定义一个"add"的函数,返回两个参数的和。
.section .text, “x”
.global add @ give the symbol add external linkage
ADD r0, r0, r1 @ add input arguments
MOV pc, lr @ return from subroutine
@ end of program
二. Linux 汇编程序中的标号
标号只能由a~z,A~Z,0~9,“.”,_等字符组成。当标号为0~9的数字时为局部标号,局部标号可以重复出现,使用方法如下:
标号f: 在引用的地方向前的标号
标号b: 在引用的地方向后的标号
【例2】使用局部符号的例子,一段循环程序
& subs r0,r0,#1 @每次循环使r0=r0-1
& bne 1f @跳转到1标号去执行
局部标号代表它所在的地址,因此也可以当作变量或者函数来使用。
三. Linux汇编程序中的分段
(1).section伪操作
用户可以通过.section伪操作来自定义一个段,格式如下:
&.section section_name [, "flags"[, %type[,flag_specific_arguments]]]
每一个段以段名为开始, 以下一个段名或者文件结尾为结束。这些段都有缺省的标志(flags),连接器可以识别这些标志。(与armasm中的AREA相同)。
下面是ELF格式允许的段标志
&标志& 含义
【例3】定义段
&.section .mysection @自定义数据段,段名为 “.mysection”
&.ascii "Temp string \n\0"
(2)汇编系统预定义的段名
.text @代码段
.data @初始化数据段
.bss @未初始化数据段
需要注意的是,源程序中.bss段应该在.text之前。
四. 定义入口点
汇编程序的缺省入口是 start标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点。
【例4】定义入口点
.section.data
& initialized data here&
.section .bss
& uninitialized data here&
.section .text
.globl _start
&instruction code goes here&
五. Linux汇编程序中的宏定义
&.macro 宏名 参数名列表 @伪指令.macro定义一个宏
&.endm @.endm表示宏结束
如果宏使用参数,那么在宏体中使用该参数时添加前缀“\”。宏定义时的参数还可以使用默认值。
可以使用.exitm伪指令来退出宏。
【例5】宏定义
.macro SHIFTLEFT a, b
.if \b & 0
MOV \a, \a, ASR #-\b
MOV \a, \a, LSL #\b
六. Linux汇编程序中的常数
(1)十进制数以非0数字开头,如:123和9876;
(2)二进制数以0b开头,其中字母也可以为大写;
(3)八进制数以0开始,如:;
(4)十六进制数以0x开头,如:0xabcd,0X123f;
(5)字符串常量需要用引号括起来,中间也可以使用转义字符,如: “You are welcome!\n”;
(6)当前地址以“.”表示,在汇编程序中可以使用这个符号代表当前指令的地址;
(7)表达式:在汇编程序中的表达式可以使用常数或者数值, “-”表示取负数, “~”表示取补,“&&”表示不相等,其他的符号如:+、-、*、 /、%、&、&&、&、&&、|、&、^、!、==、&=、&=、&&、|| 跟C语言中的用法相似。
七. Linux下ARM汇编的常用伪操作
在前面已经提到过了一些为操作,还有下面一些为操作:
数据定义伪操作: .byte,.short,.long,.quad,.float,.string/.asciz/.ascii,重复定义伪操作.rept,赋值语句.equ/.set ;
&函数的定义 ;
&对齐方式伪操作 .align;
&源文件结束伪操作.end;
.include伪操作;
&if伪操作;
&.global/ .globl 伪操作 ;
.type伪操作 ;
列表控制语句 ;
区别于gas汇编的通用伪操作,下面是ARM特有的伪操作 :.reg ,.unreq ,.code ,.thumb ,.thumb_func ,.thumb_set, .ltorg ,.pool
1. 数据定义伪操作
(1) .byte:单字节定义,如:.byte 1,2,0b01,0x34,072,'s' ;
(2) .short:定义双字节数据,如:.short 0x ;
(3) .long:定义4字节数据,如:.long 0x76565
(4) .quad:定义8字节,如:.quad 0xabcd
(5) .float:定义浮点数,如:
& .float 0f-338327\
& .E-40 @ - pi
(6) .string/.asciz/.ascii:定义多个字符串,如:
& .string "abcd", "efgh", "hello!"
& .asciz "qwer", "sun", "world!"
& .ascii "welcome\0"
需要注意的是:.ascii伪操作定义的字符串需要自行添加结尾字符'\0'。
(7) .rept:重复定义伪操作, 格式如下:
& .rept 重复次数
& 数据定义
& .endr @结束重复定义
& .byte 0x23
(8) .equ/.set: 赋值语句, 格式如下:
& .equ(.set) 变量名,表达式
& .equ abc 3 @让abc=3
2.函数的定义伪操作
(1)函数的定义,格式如下:
& 返回语句
一般的,函数如果需要在其他文件中调用, 需要用到.global伪操作将函数声明为全局函数。为了不至于在其他程序在调用某个C函数时发生混乱,对寄存器的使用我们需要遵循APCS准则。函数编译器将处理为函数代码为一段.global的汇编码。
(2)函数的编写应当遵循如下规则:
? a1-a4寄存器(参数、结果或暂存寄存器,r0到r3 的同义字)以及浮点寄存器f0-f3(如果存在浮点协处理器)在函数中是不必保存的;
? 如果函数返回一个不大于一个字大小的值,则在函数结束时应该把这个值送到 r0 中;
? 如果函数返回一个浮点数,则在函数结束时把它放入浮点寄存器f0中;
?如果函数的过程改动了sp(堆栈指针,r13)、fp(框架指针,r11)、sl(堆栈限制,r10)、lr(连接寄存器,r14)、v1-v8(变量寄存器,r4 到 r11)和 f4-f7,那么函数结束时这些寄存器应当被恢复为包含在进入函数时它所持有的值。
3. .align .end .include .incbin伪操作
(1).align:用来指定数据的对齐方式,格式如下:
& .align [absexpr1, absexpr2]
& 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或 32. 第二个表达式值表示填充的值。
(2).end:表明源文件的结束。
(3).include:可以将指定的文件在使用.include 的地方展开,一般是头文件,例如:
& .include “myarmasm.h”
(4).incbin伪操作可以将原封不动的一个二进制文件编译到当前文件中,使用方法如下:
& .incbin "file"[,skip[,count]]
& skip表明是从文件开始跳过skip个字节开始读取文件,count是读取的字数.
4. .if伪操作
根据一个表达式的值来决定是否要编译下面的代码, 用.endif伪操作来表示条件判断的结束, 中间可以使用.else来决定.if的条件不满足的情况下应该编译哪一部分代码。
.if有多个变种:
&.ifdef symbol @判断symbol是否定义
&.ifc string1,string2 @字符串string1和string2是否相等,字符串可以用单引号括起来
&.ifeq expression @判断expression的值是否为0
.ifeqs string1,string2 @判断string1和string2是否相等,字符 串必须用双引号括起来
.ifge expression @判断expression的值是否大于等于0
.ifgt absolute expression @判断expression的值是否大于0
.ifle expression @判断expression的值是否小于等于0
.iflt absolute expression @判断expression的值是否小于0
.ifnc string1,string2 @判断string1和string2是否不相等, 其用法跟.ifc恰好相反。
.ifndef symbol, .ifnotdef symbol @判断是否没有定义symbol, 跟.ifdef恰好相反
.ifne expression @如果expression的值不是0, 那么编译器将编译下面的代码
.ifnes string1,string2 @如果字符串string1和string2不相 等, 那么编译器将编译下面的代码.
5. .global .type .title .list
(1).global/ .globl :用来定义一个全局的符号,格式如下:
& .global symbol 或者 .globl symbol
(2).type:用来指定一个符号的类型是函数类型或者是对象类型, 对象类型一般是数据, 格式如下:
& .type 符号, 类型描述
.type a, @object
.size a, 4
.section .text
.type asmfunc, @function
.globl asmfunc
mov pc, lr
(3)列表控制语句:
.title:用来指定汇编列表的标题,例如:
& .title “my program”
.list:用来输出列表文件.
6. ARM特有的伪操作
(1) .reg: 用来给寄存器赋予别名,格式如下:
& 别名 .req 寄存器名
(2) .unreq: 用来取消一个寄存器的别名,格式如下:
       .unreq 寄存器别名
  注意被取消的别名必须事先定义过,否则编译器就会报错,这个伪操作也可以用来取消系统预制的别名, 例如r0, 但如果没有必要的话不推荐那样做。
(3) .code伪操作用来选择ARM或者Thumb指令集,格式如下:
           .code 表达式
  如果表达式的值为16则表明下面的指令为Thumb指令,如果表达式的值为32则表明下面的指令为ARM指令.
(4) .thumb伪操作等同于.code 16, 表明使用Thumb指令, 类似的.arm等同于.code 32
(5) .force_thumb伪操作用来强制目标处理器选择thumb的指令集而不管处理器是否支持
(6) .thumb_func伪操作用来指明一个函数是thumb指令集的函数
(7) .thumb_set伪操作的作用类似于.set, 可以用来给一个标志起一个别名, 比.set功能增加的一点是可以把一个标志标记为thumb函数的入口, 这点功能等同于.thumb_func
(8) .ltorg用于声明一个数据缓冲池(literal pool)的开始,它可以分配很大的空间。
(9) .pool的作用等同.ltorg
(9).space &number_of_bytes& {,&fill_byte&}
分配number_of_bytes字节的数据空间,并填充其值为fill_byte,若未指定该值,缺省填充0。(与armasm中的SPACE功能相同)
(10).word &word1& {,&word2&} …
插入一个32-bit的数据队列。(与armasm中的DCD功能相同)
可以使用.word把标识符作为常量使用
& valueOfStart:
& .word Start
&这样程序的开头Start便被存入了内存变量valueOfStart中。
(11).hword &short1& {,&short2&} …
插入一个16-bit的数据队列。(与armasm中的DCW相同)
八. GNU ARM汇编特殊字符和语法
代码行中的注释符号: ‘@’
整行注释符号: ‘#’
语句分离符号: ‘;’
直接操作数前缀: ‘#’ 或 ‘$’
九、GNU的编译器和调试工具
1 编译工具(1)编辑工具介绍
GNU 提供的编译工具包括汇编器as、C编译器gcc、C++编译器g++、连接器ld和二进制转换工具objcopy。基于ARM平台的工具分别为arm- linux-as、arm-linux-gcc、arm-linux-g++、arm-linux-ld和arm-linux- objcopy。GNU的编译器功能非常强大,共有上百个操作选项,这也是这类工具让初学者头痛的原因。不过,实际开发中只需要用到有限的几个,大部分可以采用缺省选项。GNU工具的开发流程如下:编写C、C++语言或汇编源程序,用gcc或g++生成目标文件,编写连接脚本文件,用连接器生成最终目标文件(elf格式),用二进制转换工具生成可下载的二进制代码。
(A)编写C、C++语言或汇编源程序
通常汇编源程序用于系统最基本的初始化,如初始化堆栈指针、设置页表、操作ARM的协处理器等。初始化完成后就可以跳转到C代码执行。需要注意的是,GNU的汇编器遵循AT&T的汇编语法,读者可以从GNU的站点(www.gnu.org)上下载有关规范。汇编程序的缺省入口是 start标号,用户也可以在连接脚本文件中用ENTRY标志指明其它入口点(见下文关于连接脚本的说明)。
(B)用gcc或g++生成目标文件
如果应用程序包括多个文件,就需要进行分别编译,最后用连接器连接起来。如笔者的引导程序包括3个文件:init.s(汇编代码、初始化硬件)xmrecever.c(通信模块,采用Xmode协议)和flash.c(Flash擦写模块)。
分别用如下命令生成目标文件: arm-linux-gcc-c-O2-oinit.oinit.s arm-linux-gcc-c-O2-oxmrecever.oxmrecever.c arm-linux-gcc-c-O2-oflash.oflash.c 其中-c命令表示只生成目标代码,不进行连接;-o命令指明目标文件的名称;-O2表示采用二级优化,采用优化后可使生成的代码更短,运行速度更快。如果项目包含很多文件,则需要编写makefile文件。关于makefile的内容,请感兴趣的读者参考相关资料。
(C)编写连接脚本文件
gcc 等编译器内置有缺省的连接脚本。如果采用缺省脚本,则生成的目标代码需要操作系统才能加载运行。为了能在嵌入式系统上直接运行,需要编写自己的连接脚本文件。编写连接脚本,首先要对目标文件的格式有一定了解。GNU编译器生成的目标文件缺省为elf格式。elf文件由若干段(section)组成,如不特殊指明,由C源程序生成的目标代码中包含如下段:.text(正文段)包含程序的指令代码;.data(数据段)包含固定的数据,如常量、字符串;.bss(未初始化数据段)包含未初始化的变量、数组等。C++源程序生成的目标代码中还包括.fini(析构函数代码)和. init(构造函数代码)等。连接器的任务就是将多个目标文件的.text、.data和.bss等段连接在一起,而连接脚本文件是告诉连接器从什么地址开始放置这些段。例如连接文件link.lds为:
ENTRY(begin)
.text:{*(.text)}
.data:{*(.data)}
.bss:{*(.bss)}
其中,ENTRY(begin)指明程序的入口点为begin标号;.=0x指明目标代码的起始地址为0x,这一段地址为 MX1的片内RAM;.text:{*(.text)}表示从0x开始放置所有目标文件的代码段,随后的.data:{* (.data)}表示数据段从代码段的末尾开始,再后是.bss段。
(D)用连接器生成最终目标文件
有了连接脚本文件,如下命令可生成最终的目标文件:
arm-linux-ld –no stadlib –o bootstrap.elf -Tlink.lds init.o xmrecever.o flash.o
其中,ostadlib表示不连接系统的运行库,而是直接从begin入口;-o指明目标文件的名称;-T指明采用的连接脚本文件(也可以使用-Ttext address,address表示执行区地址);最后是需要连接的目标文件列表。
(E)生成二进制代码
连接生成的elf文件还不能直接下载执行,通过objcopy工具可生成最终的二进制文件:
arm-linux-objcopy –O binary bootstrap.elf bootstrap.bin
其中-O binary指定生成为二进制格式文件。Objcopy还可以生成S格式的文件,只需将参数换成-O srec。还可以使用-S选项,移除所有的符号信息及重定位信息。如果想将生成的目标代码反汇编,还可以用objdump工具:
&arm-linux-objdump -D bootstrap.elf
至此,所生成的目标文件就可以直接写入Flash中运行了。(2)Makefile实例
example: head.s main.c
&arm-linux-gcc -c -o head.o head.s
&arm-linux-gcc -c -o main.o main.c
&arm-linux-ld -Tlink.lds head.o ain.o -o example.elf
&arm-linux-objcopy -O binary -S example_tmp.o example
&arm-linux-objdump -D -b binary -m arm example &ttt.s
2. 调试工具
Linux 下的GNU调试工具主要是gdb、gdbserver和kgdb。其中gdb和gdbserver可完成对目标板上Linux下应用程序的远程调试。 gdbserver是一个很小的应用程序,运行于目标板上,可监控被调试进程的运行,并通过串口与上位机上的gdb通信。开发者可以通过上位机的gdb输入命令,控制目标板上进程的运行,查看内存和寄存器的内容。gdb5.1.1以后的版本加入了对ARM处理器的支持,在初始化时加入- target==arm参数可直接生成基于ARM平台的gdbserver。gdb工具可以从ftp: //ftp.gnu.org/pub/gnu/gdb/上下载。
对于Linux内核的调试,可以采用kgdb工具,同样需要通过串口与上位机上的gdb通信,对目标板的Linux内核进行调试。可以从/projects/kgdb/上了解具体的使用方法。
参考资料:
1. Richard Blum,Professional Assembly Language
2. GNU ARM 汇编快速入门,http://blog.chinaunix.net/u/31996/showart.php?id=326146
3. ARM GNU 汇编伪指令简介,/jb8164/archive//41661.aspx
4. GNU汇编使用经验,http://blog.chinaunix.net/u1/37614/showart_390095.html
5. GNU的编译器和开发工具,/blog-htm-do-showone-uid-34335-itemid-81387-type-blog.html
6. 用GNU工具开发基于ARM的嵌入式系统,/liren0@126/blog/static//
7. objcopy命令介绍,http://blog.csdn.net/junhua198310/archive//1669545.aspx引文来源&&
阅读(2603)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
在LOFTER的更多文章
loftPermalink:'',
id:'fks_086066',
blogTitle:'[转载]吾将上下而求索-搜狐博客',
blogAbstract:'
100个最佳Linux站点 (一) 网络中遍布着大量的Linux相关站点; (二) 用户无须详细了解每一个此类站点,实际上,一百个站点足够你使用了。 评选出的这100个优秀站点,将按照下述20个类别作以评介: (一) 文件下载 (二) 幽默娱乐 (三) 相关新闻 (四) 通用硬件 (五) 专用硬件 (六) 新手站点 (七) 图形/多媒体 (八) 游戏站点 (九) 网络杂志 (十) 入口(教育、链接) (十一) 软件开发 (十二) 购物 (十三) Linux内核 (十四) 职业机会 (十五) 科学工程 ',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:8,
publishTime:2,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'生命不息,奋斗不止!!!做一个自尊自爱自强的人。',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}}

我要回帖

更多关于 winpe启动盘制作 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信