EDN首页   博客首页

最新日志

发表于:2008-1-9 12:17:05
标签:无标签

0

Getting Started with Qtopia

January 2nd, 2006 by Lorn Potter in


From the horse's mouth (Trolltech) come instructions on how to get started writing applications for Qtopia.

Trolltech's Qtopia is an embedded application framework designed to give vendors maximum customization and third-party developers the choice of developing commercial applications or free GPL applications. Qtopia is available under dual licenses. Developing for Qtopia is as easy as any Qt/KDE desktop development, except for a few extra steps and tools needed.

I started developing my program Gutenbrowser, which is a reader/downloader for the thousands of free etexts available from Project Gutenberg. It started out as a Linux-only application and soon made its way to Windows, Qtopia and then to the Open Palmtop Integrated Environment (Opie). Opie is based on Qtopia GPL and is community developed.

Qtopia is built on Qt Embedded, so an application that is created with Qt easily can be made to run in the Qtopia environment. It took about two weeks part-time/open-source-developer time to get Gutenbrowser running on the Sharp Zaurus, and that includes learning Qtopia API and cross-platform compilation as well!

If you want to port a Qt 4 application to Qtopia, it would be best to wait for Qtopia 4 to be released, as there are significant changes between Qt Embedded 2.3 and Qt Embedded 4. Qt 3, KDE and even Gtk+ applications have been ported to Qtopia versions 1 and 2 but require back-porting, class substitution and the use of microkde sources for the KDE programs.

Tools You Need

To get started developing for Qtopia, you need a few tools. Qtopia is Linux-only currently, so you need a Linux desktop on which to develop. You also obviously need an editor, such as emacs or vi. For this project, I chose KDevelop as it comes with a simple Qtopia application template.

If you are developing for a device, you need a cross-compiler. Our target device, the Archos PMA430 uses arm-linux-gcc version 2.95 for Qtopia. Although gcc 3 produces better optimized code, we want to run on and be compatible with software currently existing on hardware, so 2.95, as old as it is, will do. You can get ARM cross-toolchains from various sites on the Internet. In this case, Archos has a toolchain available at www.archos.com/products/overview/pma_400_sdk.html and links are also available from qtopia.net.

Source Code or SDK?

Of course, you also need Qtopia, but you have the choice of downloading the source code or using a ready-made Qtopia SDK. The SDK for the PMA430 is available in commercial and GPL versions, just like Qtopia itself. The commercial SDK can be purchased for a reasonable sum from www.trolltech.com/products/qtopia/pricing.html, and the free, GPL version can be downloaded from ftp.trolltech.com/qtopia/sdk. These install to /opt/Qtopia. Then from a command prompt do:

# ln -s /opt/Qtopia/sharp /opt/Qtopia/arm

if there is no /opt/Qtopia/arm directory.

KDevelop Project

Start KDevelop, and from the Project menu choose New Project. Open the C++ directory icon, under the directory Embedded. Click the file called Qtopia Application to start a new Qtopia project. I could name this anything, like hippopotamus, but instead I will name my project skizzy. See Figure 1 for an example dialog for creating this project.


Figure 1. Creating the skizzy Project

Once you have a project, you can start editing it to suit your needs. You need to be sure to use Designer from Qt 2 when you edit .ui (user interface) files for Qtopia,
 as .ui files generated from later versions of Qt are not compatible. I do this by setting up a custom external tool and then opening my .ui file from within Designer 2.

Note: do not open by clicking on the .ui file, because Designer 3 will open up within KDevelop, and you can mangle your .ui file. Because of this, you have to run KDevelop
from a command line, after exporting a few variables:

export PATH=/opt/Qtopia/bin:$PATH
export LD_LIBRARY_PATH=/opt/Qtopia/lib:$LD_LIBRARY_PATH

You also want to set up the Qt Virtual framebuffer tool by the name of QVFb, pointing to /opt/Qtopia/bin/qvfb, in which the application will run on the desktop.
Qtopia displays directly to the framebuffer, and therefore it does not need the overhead of the X-11 display server.
Setting Up the Development Environment

We need to set some environmental variables for our KDevelop project. Run KDevelop, and then click on Project→Project Options→Run Options. Add these variables:

Name: QTDIR Value: /opt/Qtopia
Name: QPEDIR Value: /opt/Qtopia
Name PATH Value: /opt/Qtopia/bin:$PATH
Name LD_LIBRARY_PATH Value: /opt/Qtopia/lib:$LD_LIBRARY_PATH

Similarly, add to the Make Options, for desktop development:

Name: QTDIR Value: /opt/Qtopia
Name: QPEDIR Value: /opt/Qtopia
Name PATH Value: /opt/Qtopia/bin:/opt/Qtopia/tmake/bin:$PATH
Name LD_LIBRARY_PATH Value: /opt/Qtopia/lib:$LD_LIBRARY_PATH
Name TMAKEPATH Value:/opt/Qtopia/tmake/lib/qws/linux-generic-g++

Add -lqtopia to the LIBS line in skizzy.pro, as Qtopia 1.7 adds a new library.

At this point, you need to generate a Makefile manually, as KDevelop does not use tmake correctly:

# export TMAKEPATH=/opt/Qtopia/tmake/lib/qws/linux-generic-g++
# tmake -o Makefile skizzy.pro

Then you can build the project (F8) from within KDevelop. This little glitch will be resolved in newer versions of Qtopia that use qmake
to generate Makefiles.
Getting Gritty

Let's add some functionality to skizzy.

Start the Designer 2 application and open skizzybase.ui, and delete the QLabel. Add a QTabWidget with a QComboBox on the first tab, a QListBox on
the second tab and a QMultiLineEdit
on the third tab, for example (Figure 2).

Figure 2. If you use QLayouts, it allows your application to resize depending on the display resolution or screen rotation.

Save the .ui file.

Open the file skizzy.cpp with KDevelop. You will see our application is derived from skizzyBase:

skizzy::skizzy( QWidget* parent,  const char* name, WFlags fl )
    : skizzyBase( parent, name, fl )

I want to change main.cpp to a better method of constructing the application that was added since the time that the Qtopia templates for KDevelop were created.

We change the usual main() function:

int main( int argc, char ** argv )
{
    QPEApplication a( argc, argv );
    skizzy mw;
    a.showMainWidget( &mw );
    return a.exec();
}


to Qtopia's application macro:

QTOPIA_ADD_APPLICATION("skizzy",skizzy);
QTOPIA_MAIN

This allows us to create a quicklaunch application, which helps speed up startup time, by using the common application constructor that is already in memory.

My application skizzy doesn't do anything yet, so include:

#include

Add a private member:

FontDatabase fdb;

and some functions as private slots:

private slots:
void fillCombo();
void comboSelected(const QString &);
void showFont( QListBoxItem *);


We need to add a few lines in skizzy.cpp here for things we will use:

#include
#include
#include
#include
#include
#include
#include

#include

and then add the implementations, to which we will connect our widgets signals:

/*
This function uses Qtopia's FontDatabase to
fill the combobox with a list of font names.*/
void skizzy::fillCombo()
{
    QStringList families = fontdb.families();
      for ( QStringList::Iterator f = families.begin(); f != families.end();++f ) {
          QString family = *f;
        ComboBox1->insertItem( family);
    }
}

/*
This gets called when the combobox is selected, and
fills the listbox on the second tab with the name,
style and point size for the family of fonts
selected, and raises it. */
void skizzy::comboSelected(const QString &selectedFont)
{
ListBox1->clear();

 QStringList styles = fdb.styles( selectedFont );
      for ( QStringList::Iterator s = styles.begin(); s != styles.end();++s ) {
              QString style = *s;
              QValueList smoothies = fdb.smoothSizes( selectedFont, style );
               for ( QValueList::Iterator points = smoothies.begin(); points != smoothies.end(); ++points ) {
                   QString pointSize = selectedFont + " "+ style +" "+QString::number( *points ) + " ";
                  ListBox1 ->insertItem( pointSize);
               }
           }
    TabWidget2->showPage(tab2);
}

/*
This shows example text of the selected font in
the QMultiLineWidget on the 3rd tab, and raises it.*/
void skizzy::showFont( QListBoxItem *item)
{
    QStringList fontItemString = QStringList::split(' ',item->text());
    QString family, style, point;

    family = fontItemString[0];
    style = fontItemString[1];
    point = fontItemString[2];
    bool ok;
    int i_size = point.toInt(&ok,10);

    if (!ok) {
        style += " "+fontItemString[2];
        point = fontItemString[3];
        i_size = point.toInt(&ok,10);
    }

    QFont selectedFont( family);
    selectedFont.setPointSize(i_size);

     if(style.find("Italic",0,TRUE) != -1) {
          selectedFont.setItalic(TRUE);
     }

     if(style.find("Bold",0,TRUE) != -1) {
        selectedFont.setWeight(QFont::Bold);
     }

     if(style.find("Light",0,TRUE) != -1) {
        selectedFont.setWeight(QFont::Light);
    }

    MultiLineEdit1->setFont( selectedFont);
    MultiLineEdit1->setText( tr( "The Quick Brown Fox Jumps Over The Lazy Dog" ) );
    MultiLineEdit1->setWordWrap( QMultiLineEdit::WidgetWidth);

    TabWidget2->showPage(tab3);
}


Qt and Qtopia use signals for sending messages between widgets. Every widget has some kind of signal it emits, and we can use the connect macros to link up functionality.

Connect ComboBox1's activated signal, and ListBox1's clicked signal to our slots, like this:

skizzy::skizzy( QWidget* parent,  const char* name, WFlags fl )
    : skizzyBase( parent, name, fl )
{
    connect(bye, SIGNAL(clicked()), this, SLOT(goodBye()));
    connect(ComboBox1, SIGNAL(activated(const QString &)), this, SLOT(comboSelected(const QString &)));
    connect(ListBox1, SIGNAL( clicked ( QListBoxItem * )), this, SLOT(showFont( QListBoxItem*)));
    fillCombo();
}


Notice how the slot function takes an argument of the exact same type as the signal.

In KDevelop, either press F8, or in the menu, select Build→Build Project.

It should now compile, using the native compiler. To run it, start up QVFb, and simply select Build→Execute Main Program. The skizzy application should show up in QVFb.


Figure 3. Skizzy with real, if not useful features.
Cross-Compiling

So, now that we have a reasonably working program, we need to cross-compile this for the Archos device. We have to change the project settings to find the proper libraries.

We are now ready to cross-compile, so clean the project by selecting Build→Clean Project from the menu.

You need to change the Make Options, using the Project Options→Make Options dialog:

Name: QTDIR Value: /opt/Qtopia/arm
Name: QPEDIR Value: /opt/Qtopia/arm
Name PATH Value: /usr/local/arm/bin:/opt/Qtopia/tmake/bin:$PATH
Name TMAKEPATH Value:/opt/Qtopia/tmake/lib/qws/linux-arm-g++

Delete the Makefile, and run the following command from the command line to create the Makefile for compiling using the arm-linux compiler:

# export TMAKEPATH=/opt/Qtopia/tmake/lib/qws/linux-arm-g++
# tmake -o Makefile skizzy.pro

Press F8 to build the project. You can now take the resulting binary, transfer it to the Archos device using USB, and run it from there!

If you want to create an installable package, Qtopia uses the Itsy Package Management (ipkg) available from handhelds.org, to install things using the Software Packages application. More information about ipkg and Qtopia development are available from Trolltech's Qtopia.net Web site.

Lorn Potter works for Trolltech as the Qtopia Community Manager. He is an American who lives in sunny Brisbane, Australia, with his Australian wife and son. He is a self-taught open-source programmer who is a core developer for the Opie (Open Palmtop Integrated Environment) Project. He also has worked as a musician, sound engineer and snow ski bum.

原文地址:http://www.linuxjournal.com/article/8691

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(0) | 阅读(387)
发表于:2007-10-22 16:16:42
标签:无标签

0

ARM架构方案

CPU Description ISA Process Voltage Area(mm2) Power(mW) Clock(MHz) Mips(MHz)
ARM7TDMI Core V4T 0.18u 1.8V 0.53 <0.25 60-110 0.9
ARM7TDMI-S Synthesizable Core V4T 0.18u 1.8V <0.8 <0.4 >50 0.9
ARM9TDMI Core V4T 0.18u 1.8V 1.1 0.3 167-220 1.1
ARM920T Macrocell 16+16KB cache V4T 0.18u 1.8V 11.8 0.9 140-200 1.05
ARM940T Macrocell 8+8KB cache V4T 0.18u 1.8V 4.2 0.85 140-170 1.05
ARM9E-S Synthesizable Core V5TE 0.18u 1.8V ? ~1 133-200 1.1
ARM1020E Macrocell 32+32kb cache V5TE 0.15u 1.8V ~10 ~0.85 200-400 1.24

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 整理

评论(0) | 阅读(448)
发表于:2007-9-25 13:28:40
标签:无标签

1

C.plus.plus.GUI.Programming.with.Qt.4

 3 FindDialog::FindDialog(QWidget *parent)
4 : QDialog(parent)
5 {
6 label = new QLabel(tr("Find &what:"));
......
On line 4, we pass on the parent parameter to the base class constructor.

The return value is ignored when a slot is executed in response to a signal, but when we call a slot as a function the return value is available to us just as it is when we call any ordinary C++ function.

A dialog is modeless if it's invoked using show() (unless we call setModal() beforehand to make it modal); it is modal if it's invoked using exec().

点击此处查看原文 >>

系统分类: 软件开发   |    用户分类:    |    来源: 整理

评论(0) | 阅读(464)
发表于:2007-9-4 15:41:44
标签:无标签

1

读:C++编程思想 Thinking in C++

第一章:
后时髦哲学的基本原则是:任何具有自己独特生活方式的组织,其主要目标就是使这种生活方式永存
"带着锤子三年,看什么都是钉子"

第二章:

p33

点击此处查看原文 >>

系统分类: 软件开发   |    用户分类:    |    来源: 整理

评论(0) | 阅读(536)
发表于:2007-8-23 15:01:01
标签:无标签

1

读:Expert C Programming -- Deep C Secrets

代码:
    if(i==3)
    if(3==i)

dog one's steps

Chapter 1.
   const
 
Chapter 2.
    一个'L'的NUL用于结束一个ASCII字符串
    两个'L'的NULL用于表示什么也不指向(空指针).

    C语言中的符号重载

Symbol

Meaning

static

在函数内部,表示改变量的值在各个调用间一直保持连续性

(Inside a function, retains its value between calls)

在函数这一级,表示函数只对本文件可见

extern

用于函数定义,表示全局可见(属于冗余的)

用于变量,表示它定义在其他地方

void

作为函数的返回类型,表示不返回任何数值 void function()

在指针声明中,表示通用指针的类型 void *ptr;

位于参数列表中,表示没有参数   function(void)

*

乘法运算符

用于指针,间接引用  *ptr = 0 ;

在声明中,表示指针   char *ptr

位的AND操作符

取地址操作符

=

赋值符

==

比较运算符

<= 

小于等于运算符

<<=

左移复合赋值运算符

< 

小于运算符

#include指令的左定界符

( )

在函数定义中,包围形式参数表

调用一个函数

改变表达式的运算顺序

将值转换成其他类型(强制类型转换)

定义带参数的宏

包围sizeof操作符的操作数(如果它是类型名) sizeof(int)


   
    C语言运算符优先级存在的问题       

优先级问题

表达式

人们可能误认为的结果

实际结果

.的优先级高于*

->操作符用于取消这个问题

*p.f

P所指向的字段f  (*p).f

The f field of what p points to

pf偏移,作为指针然后进行解除引用操作 *(p.f)

 

[ ]高于*

int *ap[ ]

ap是个指向int型数组的指针

int(*ap)[ ]

ap是个以指向int型的指针为元素的数组 int * (ap[ ])

函数( )高于*

int *fp( )

fp是个函数指针,该函数返回int int(*fp)( )

fp是个是个函数,返回int *

 int *(fp( ))

===!高于运算符

(val&mask!=0)

(val&mask)!=0

val&(mask!=0)

===!高于赋值符

c=getchar()!=EOF

(c=getchar())!=EOF

c=(getchar()!=EOF)

算术运算法高于移位运算符

msb<<4 + lsb

(msb<<4)+lab

msb<<(4+lsb)

逗号运算符在所有运算符中优先级最低

i=1,2

i=(1,2)

(i=1),2

             
Chapter 3.
       C语言的声明         

       There's some good news and some bad news associated with unions. The bad news is that the good news isn't all that good.

        理解C语言声明的优先级规则

A  声明从它的名字开始读取,然后按照优先级次序一次读取

B 优先级从高到低依次是:

    B.1 声明中被括号括起来的那部分.

    B.2 后缀操作符:

           括号( )表示这是一个函数,而方括号[ ]表示这是一个数组.

    B.3 前缀操作符: *表示这是一个"指向...的指针"

C 如果const和(或)volatile关键字的后面紧跟着类型说明符(如int,long等),那么它作用于类型说明符.在其他情况下const和(或)volatile关键字作用于它左边紧邻的指针星号.

typedef和宏文本替换的区别(2点):

 1.可以用其他的类型说明符对宏类型名进行扩展,但对typedef所定义的类型名却不能这样做.

    #define peach int

    unsigned peach i;/*没问题*/


    typedef int banana;

    unsigned banana i;/*错误!非法*/

2.在连续几个变量的声明中,用typedef定义的类型能够保证声明中所有变量均为同一种类型,而用#define定义的类型则无法保证.

    #define int_ptr int *

    int_ptr chalk , cheese;

经宏扩展,第二行变为 int * chalk , cheese; 这使得chalk为 int * 而cheese为int

    typedef char * char_ptr;

    char_ptr Bently , Rollce_Royce;

Bently和Rollce_Royce为同一类型.

Chapter 4.

声明和定义

声明相当于普通的说明:它说明的并非自身,而是描述其他地方创建的对象.可以出现多次.

定义相当于的特殊的说明:它为对象分配内存.只能出现在一个地方.

Chapter 4.

函数库链接的5个秘密:

1.动态库文件的扩展名是".so",静态库文件的扩展名是".a"

2.例如,通过-lthread选项,告诉编译器链接到"libthread.so",即使用"-l"就可把name扩展成libname.so

3.编译器期望在确定的目录找到库.

4.观察头文件,确认所使用的函数库.

5.与提取动态库中的符号相比,静态库中符号提取的方法限制更严.

Chapter 7.

const和volatile类型修饰符修改的是左边紧邻的项目.

地址对齐:访问一个8字节的double数据,其地址必须是8的整数倍.所以一个double型的数据只能存储在24,8008或32768,但不能存储在地址1006(因为它无法被8整除).

p188


点击此处查看原文 >>

系统分类: 软件开发   |    用户分类:    |    来源: 整理

评论(0) | 阅读(537)
发表于:2007-7-17 0:21:16
标签:无标签

1

ARM 汇编指令条件执行详解

ARM模式下,任何一条数据处理指令可以选择是否根据操作的结果来更新CPSR寄存器中的ALU状态标志位。在数据处理指令中使用S后缀来实现该功能。

不要在CMP,CMN,TST或者TEQ指令中使用S后缀。这些比较指令总是会更新标志位。

Thumb模式下,所有数据处理指令都更新CPSR中的标志位。有一个例外就是:当一个或更多个高寄存器被用在MOVADD指令时,此时MOVADD不能更新状态标志.

几乎所有的ARM指令都可以根据CPSR中的ALU状态标志位来条件执行。参见表2-1条件执行后缀表。

ARM模式下,你可以:

· 根据数据操作的结果更新CPSR中的ALU状态标志;

· 执行其他几种操作,但不更新状态标志;

· 根据当前状态标志,决定是否执行接下来的指令。

Thumb模式,大多数操作总是更新状态标志位,并且只能使用条件转移指令(B)来实现条件执行。该指令(B)的后缀和在ARM模式下是一样的。其他指令不能使用条件执行。

2.5.1 ALU状态标志

CPSR寄存器包含下面的ALU状态标志:

点击看大图

2.5.2 执行条件

N,Z,C,V相关的条件码后缀如下表所列:

点击看大图

举例说明:

 

示例1:

ADD            r0, r1, r2              ; r0 = r1 + r2, 不更新标志位

ADDS         r0, r1, r2      ; r0 = r1 + r2, 后缀S表示更新标志位

ADDCSS     r0, r1, r2      ; If C 标志为1,则执行r0 = r1 + r2, 且更新标志,

CMP             r0, r1            ; CMP指令肯定会更新标志.

 

示例2(请自行分析)

gcd        CMP r0, r1

BEQ end

BLT less

SUB r0, r0, r1

B gcd

less

SUB r1, r1, r0

B gcd

end

 

点击此处查看原文 >>

系统分类: 嵌入式   |    用户分类:    |    来源: 转贴

评论(1) | 阅读(1325)
发表于:2007-7-17 0:16:17
标签:无标签

1

ARM汇编指令集

一、 跳转指令    跳转指令用于实现程序流程的跳转,在ARM程序中有两种方法可以实现程序流程的跳转:
Ⅰ.使用专门的跳转指令。
Ⅱ.直接向程序计数器PC写入跳转地址值。
通过向程序计数器PC写入跳转地址值,可以实现在4GB的地址空间中的任意跳转,在跳转之前结合使用
MOV LRPC
等类似指令,可以保存将来的返回地址值,从而实现在4GB连续的线性地址空间的子程序调用。
    ARM指令集中的跳转指令可以完成从当前指令向前或向后的32MB的地址空间的跳转,包括以下4条指令:
1、  B指令
B指令的格式为:
B{条件}  目标地址
B指令是最简单的跳转指令。一旦遇到一个 B 指 令,ARM 处理器将立即跳转到给定的目标地址,从那里继续执行。注意存储在跳转指令中的实际值是相对当前PC值的一个偏移量,而不是一个绝对地址,它的值由汇编器来 计算(参考寻址方式中的相对寻址)。它是 24 位有符号数,左移两位后有符号扩展为 32 位,表示的有效偏移为 26 位(前后32MB的地址空间)。以下指令:
B       Label         ;程序无条件跳转到标号Label处执行
     CMP R1,#0             ;当CPSR寄存器中的Z条件码置位时,程序跳转到标号Label处执行
BEQ Label      
2、  BL指令
BL指令的格式为:
BL{条件} 目标地址
BL 是另一个跳转指令,但跳转之前,会在寄存器R14中保存PC的当前内容,因此,可以通过将R14 的内容重新加载到PC中,来返回到跳转指令之后的那个指令处执行。该指令是实现子程序调用的一个基本但常用的手段。以下指令:
   BL   Label         ;当程序无条件跳转到标号Label处执行时,同时将当前的PC值保存
R14
3、  BLX指令
BLX指令的格式为:
BLX  目标地址
BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工作状态有ARM状态切换到Thumb状态,该指令同时将PC的当前内容保存到寄存器R14中。因此,当子程序使用Thumb指令集,而调用者使用ARM指令集时,可以通过BLX指令实现子程序的调用和处理器工作状态的切换。同时,子程序的返回可以通过将寄存器R14值复制到PC中来完成。
4、  BX指令
BX指令的格式为:
BX{条件}  目标地址
BX指令跳转到指令中所指定的目标地址,目标地址处的指令既可以是ARM指令,也可以是Thumb指令。
二、数据处理指令数据处理指令可分为数据传送指令、算术逻辑运算指令和比较指令等。
数据传送指令用于在寄存器和存储器之间进行数据的双向传输。
算术逻辑运算指令完成常用的算术与逻辑的运算,该类指令不但将运算结果保存在目的寄存器中,同时更新CPSR中的相应条件标志位。
比较指令不保存运算结果,只更新CPSR中相应的条件标志位。
数据处理指令共以下16条。
1、    MOV指令
MOV指令的格式为:
MOV{条件}{S} 目的寄存器,源操作数
MOV指令可完成从另一个寄存器、被移位的寄存器或将一个立即数加载到目的寄存器。其中S选项决定指令的操作是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。
指令示例:
MOV R1R0                        ;将寄存器R0的值传送到寄存器R1
MOV PCR14                       ;将寄存器R14的值传送到PC,常用于子程序返回
MOV R1R0
LSL3                 ;将寄存器R0的值左移3位后传送到R1
2、  MVN指令
MVN指令的格式为:
MVN{条件}{S} 目的寄存器,源操作数
MVN指令可完成从另一个寄存器、被移位的寄存器、或将一个立即 数加载到目的寄存器。与MOV指令不同之处是在传送之前按位被取反了,即把一个被取反的值传送到目的寄存器中。其中S决定指令的操作是否影响CPSR中条 件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。
指令示例:
MVN  R0,#0                       ;将立即数0