中国Linux公社论坛's Archiver

shang79 发表于 2004-8-29 15:17

HelloWorld on Skyeye,新手请进!

<chyyuu>最简单的可以在skyeye上运行的程序!

介绍:    初始学习嵌入式系统编程和使用Skyeye的人往往不知道该如何入手,
我想除了看资料以外,最好还有简单的例子可以用来作为基础练习。一般学习新
的编程和工具,都是从helloworld入手,所以我参考ucos-ii,使得用最少的代码
实现在skyeye上打印helloworld字串的功能。注意这里的Hello4Skyeye程
序与以前介绍的skyeye上的helloworld程序不同:它不需要有操作系统底层支
持,比如uclinux;它不是应用程序;它直接往串口写字符。Hello4Skyeye代
码量很少,没有实际应用意义,只是新手用于练习使用,高手就不必看了,欢迎
检查。

编译运行:    Hello4Skyeye程序是在Skyeye0.8.6,RedHat9.0上编译
通过的。编译之前请确定安装了Skyeye和arm-elf交叉编译器。有关这两者的安
装说明可以在论坛置顶的《Skyeye使用简介》中找到。步骤如下:
1  把Hello4Skyeye.tgz下载到Linux用户目录中用
   tar -zxvf Hello4Skyeye.tgz 解压缩Hello4Skyeye.tgz, 产生
   Hello4Skyeye目录
2 cd Hello4Skyeye
3  用make编译
4  用skyeye hello运行hello,和其它程序一样接着用tar sim; load;run;
就可以看到以下结果:
[quote]***************************************************************
**** ****
**** SkyEye Simulator Ver 0.8.6 with GDB 5.3 Interface ****
**** ****
***************************************************************
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This SkyEye was configured as "--host=i686-pc-linux-gnu --
target=arm-elf"...(no debugging symbols found)...
(SkyEye) tar s
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name at91, mach_init addr 0x813dae4
log_info: log is off.
log_info:log file is /tmp/sk1.log, fd is 0x829e0e0
log_info: log start clock 0
log_info: log end clock 200000
SKYEYE: use arm7100 mmu ops
Connected to the simulator.
(SkyEye) load
Loading section .text, size 0x98 vma 0x1000000
Loading section .data, size 0x1000 vma 0x1002000
Start address 0x1000000
Transfer rate: 33984 bits in <1 sec.
(SkyEye) run
Starting program: /home/shang/HelloForSkyeye/hello
helloworldhelloworldhelloworldhelloworldhelloworldhelloworld
helloworldhelloworldhelloworldhelloworldhelloworldhelloworld
helloworldhelloworldhelloworldhelloworld    [/quote]

组成部分:    在Hello4Skyeye目录中用make clean命令可以删除目标代
码,只留下源代码,可以看到总共只有hello.c hello.lds makefile
skyeye.conf start.S五个文件。下面逐一介绍。

makefile:   该文件做为make工具的输入,描述了该如何编译
HelloForSkyeye项目。有关makefile的编写在make.info中已经详细说明,值
得注意的是有些编译参数比较陌生,象-mapcs,-march,... 这些参数的说明可以
在as.info::Machine Dependence::ARM-Dependent::ARM Options中找到。

start.S:    该文件存放了启动的汇编代码,主要工作就是设置IRQ模式,屏蔽中
断,调用hello函数输出字串,重新循环。这里的汇编指令都是ARM指令,但是伪
指令,还有label,立即数等等都和教科书上写的ARM程序大相径庭。这些都是
GNU AS汇编编译器的统一语法。在as.info中有详细的介绍。

hello.c:    这是一个c语言源文件,其中只有一个hello函数,实现向串口输出
“helloworld" 字串的功能。因为AT91的UART0的基址为0xfffd0000,USART
发送寄存器US_THR的偏移量是0x1c。所以向0xfffd001c地址写入字符,就是
向串口发送字符。Skyeye就会把字符打印到屏幕上。可以看到系统编程必须对硬
件了解。

hello.lds:  这是ld链接器的脚本文件,其中规定了程序入口,各个段的放置位
置。ld script的书写方法可以在ld.info::Scripts::中找到。编译好的目标代码,
还可以用'objdump -x' 查看里面的各段的位置。

skyeye.conf: skyeye运行的配置文件,其中说明了模拟的cpu,arch,还有内存
组配置。论坛置顶的《Skyeye使用简介》中详细说明了该配置文件的写法。

chyyuu 发表于 2004-8-30 22:08

很好的初学例子!

quantumm 发表于 2004-12-2 00:41

Where download the "HelloForSkyeye.tar"?THX
or mail me n26881387@yahoo.com.tw

shang79 发表于 2004-12-2 01:20

If you log in as a formal user not a guest, you can see the link of Helloforskyeye.tar under my first post.
Anyway, I have send Helloforskyeye.tar to your mailbox.

quantumm 发表于 2004-12-3 00:21

I get it ! THX!

wenwencarol 发表于 2004-12-3 18:44

thank you very much!

gulite 发表于 2005-1-27 11:48

我想在skyeye里代码级调试这个程序,我修改了makefile,在CFLAGS里加上了-g,如下:

...
CFLAGS=-g ...
...

之后用skyeye载入hello,发生如下错误:
Dwarf Error: bad offset (0x1003000) in compilation unit header (offset 0x0 + 6)

不知道这是怎么回事?请教代码级调试的入门方法

谢谢

shang79 发表于 2005-2-16 15:54

hello4skyeye的源码级调试方法

[b]问题描述如下:[/b]

在Makefile中的CFLAG中添加-g选项编译hello4skyeye后,如果使用break,list命令就会出现以下提示

No symbol table is loaded. Use the "file" command.

如果使用file hello的命令则会出现错误提示:

Reading symbols from hello.elf...Dwarf Error: bad offset (0x1003000) in compilation unit header (offset 0x0 + 6).

[b]解决方法如下:[/b]

修改hello.lds文件,在SECTIONS中,最后添加以下 Stabs debugging sections.  部分代码:
[code:1]/*
* hello.lds
* ld script for helloforSkyeye
*
* author: SU Hang
* Date:   2004-08-28
*/

OUTPUT_ARCH(arm)
ENTRY(begin)
SECTIONS
{
        . = 0x1000000;
        .text : {*(.text)}

        . = ALIGN(8192);

        .data : {*(.data)}

        .bss : {*(.bss)}

        /* Stabs debugging sections.    */
        .stab 0 : { *(.stab) }
        .stabstr 0 : { *(.stabstr) }
        .stab.excl 0 : { *(.stab.excl) }
        .stab.exclstr 0 : { *(.stab.exclstr) }
        .stab.index 0 : { *(.stab.index) }
        .stab.indexstr 0 : { *(.stab.indexstr) }
        .comment 0 : { *(.comment) }
        .debug_abbrev 0 : { *(.debug_abbrev) }
        .debug_info 0 : { *(.debug_info) }
        .debug_line 0 : { *(.debug_line) }
        .debug_pubnames 0 : { *(.debug_pubnames) }
        .debug_aranges 0 : { *(.debug_aranges) }

}[/code:1]
然后再用-g参数编译链接产生的hello程序就可以进行源码级调试了,调试示例见本贴最后。现在说明一下hello.lds文件的作用和该错误的原因。

hello.lds文件是一个链接控制脚本文件(Linker Control Scripts)。该文件的作用是在链接过程中,描述输入文件(*.o)的各部分(section)是如何组合映射到输出文件(hello)的各段(segment)中的。

通常情况下,链接器ld运行时会使用一个默认的lds文件,不需要用户自己编写lds文件。该默认lds文件的内容可以在使用ld时使用--verbose参数显示。但是在特定情况下,比如编写操作系统内核,就会需要编写自己的lds文件。

hello4skyeye可以被看做一个非常简单的操作系统内核,所以得要自己编写hello.lds文件。hello.lds文件中描述了如何把start.o,hello.o文件中得代码段、数据段等等如何组合到hello。

本来有了.text .data .bss三个段,hello程序就可以在skyeye上运行了,但是如果是调试版的hello程序,就需要把start.o和hello.o中更多的与调试相关的section放入hello中,这就是我们为什么要在hello.lds中添加更多代码的原因了。

更多的关于lds方面资料,可以在Linux中使用info ld看Scripts章节。《Linker & Loader》中也有关于link Control Scripts方面的说明。


[quote][root@shang HelloForSkyeye]# make  编译hello可执行文件
arm-elf-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes start.S
arm-elf-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes hello.c
arm-elf-ld -p -X -Thello.lds start.o hello.o -o hello
arm-elf-objdump -S hello > hello.s
arm-elf-readelf -a hello > hello.r
arm-elf-nm hello > hello.n
[root@shang HelloForSkyeye]# skyeye hello  运行hello可执行文件
***************************************************************
**** ****
**** SkyEye Simulator Ver 0.8.6 with GDB 5.3 Interface ****
**** ****
***************************************************************
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This SkyEye was configured as "--host=i686-pc-linux-gnu --target=arm-elf"...
(SkyEye) tar s
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name at91, mach_init addr 0x813efa4
log_info: log is off.
log_info:log file is /tmp/sk1.log, fd is 0x829a318
log_info: log start clock 0
log_info: log end clock 200000
SKYEYE: use arm7100 mmu ops
Connected to the simulator.
(SkyEye) load
Loading section .text, size 0x54 vma 0x1000000
Loading section .rodata, size 0xb vma 0x1000054
Loading section .data, size 0x1000 vma 0x1002000
Start address 0x1000000
Transfer rate: 33528 bits in <1 sec.
(SkyEye) list           显示hello可执行文件中的源代码
1 /*
2 * hello.c
3 * just a function used to output "helloworld" to uart
4 *
5 * author: SU Hang
6 * date: 2004-08-28
7 */
8 void hello(void)
9 {
10 int i;
(SkyEye) list
11 char * hellostr="helloworld";
12 long* paddr=(long*)0xfffd001c;
13
14 for(i=0;i<10;i++)
15 {
16 * paddr=hellostr[i];
17 }
18 return;
19 }
20
(SkyEye) break hello  在hello函数入口设置断点
Breakpoint 1 at 0x1000030: file hello.c, line 14.
(SkyEye) run          程序运行到hello断点处停止
Starting program: /home/suhang/HelloForSkyeye/hello

Breakpoint 1, hello () at hello.c:14
14 for(i=0;i<10;i++)
(SkyEye) info all-register 显示当前skyeye虚拟机中所有寄存器的值
r0 0xd2 210
r1 0xfffd001c -196580
r2 0x0 0
r3 0x0 0
r4 0x0 0
r5 0x0 0
r6 0x0 0
r7 0x0 0
r8 0x0 0
r9 0x0 0
r10 0x0 0
r11 0x1001ffc 16785404
r12 0x1002000 16785408
sp 0x1001ff0 16785392
lr 0x0 0
pc 0x1000030 16777264
f0 0 (raw 0x000000000000000000000000)
f1 0 (raw 0x000000000000000000000000)
f2 0 (raw 0x000000000000000000000000)
f3 0 (raw 0x000000000000000000000000)
f4 0 (raw 0x000000000000000000000000)
f5 0 (raw 0x000000000000000000000000)
f6 0 (raw 0x000000000000000000000000)
f7 0 (raw 0x000000000000000000000000)
fps 0x0 0
cpsr 0xd2 210[/quote]

zxlufei 发表于 2005-2-20 22:44

感谢楼主,按你的方法偶在ROOT登陆时运行成功了,不过非ROOT时登陆可以吗?
(SkyEye) target sim
cpu info: armv3, arm7tdmi, 41007700, fff8ff00, 0
mach info: name at91, mach_init addr 0x813e02c
log_info: log is off.
SkyEye: Error when open log file:  : 权限不够
[zxlufei@localhost HelloForSkyeye]$
这个是什么原因?请指点~万分感谢!

shang79 发表于 2005-2-22 01:35

出现"SkyEye: Error when open log file"的错误是因为skyeye.conf文件中把log文件设为/tmp/sk1.log,因为普通用户没有权限打开该文件写入skyeye日志,所以会报错.

解决的方法的方法是把Hello4Skye目录中的skyeye.conf文件中的下面语句:

log: logon=0, logfile=/tmp/sk1.log, start=0, end=200000

改为

log: logon=0, logfile=./sk1.log, start=0, end=200000

应该就可以了,要保证logfile是普通用户可以打开的文件.

zxlufei 发表于 2005-2-26 10:29

多谢楼主,按楼主指点,在非root下也成功了~

littertiger 发表于 2005-2-27 21:22

I have two arm tool chains, one is arm-linux-xxx (3.3.2), the other is arm-elf-xxx. which should I use? what's the difference?
when use arm-elf-xxx:
error:invalid option 'short-load-bytes'
when use arm-linux-xxx:
arm-linux-ld:hello:not enough room for program headers, try linking with -N
  when I use -N to link: no error, but no "hello" is outputed when run in skyeye.

why?

tropic 发表于 2005-2-28 14:41

我遇到楼上相同的问题啊?不知怎么解决呢?
arm-unknown-linux-gnu-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes  start.S
arm-unknown-linux-gnu-gcc -c -Wall -Wstrict-prototypes -Wno-trigraphs -O2 -pipe -g -mapcs-32 -march=armv4 -mtune=arm7tdmi -mshort-load-bytes  hello.c
arm-unknown-linux-gnu-ld -p -X -Thello.lds  start.o hello.o -o hello
arm-unknown-linux-gnu-ld: hello: Not enough room for program headers, try linking with -N
arm-unknown-linux-gnu-ld: final link failed: Bad value
make: *** [hello] Error 1

shang79 发表于 2005-3-2 13:31

非常感谢楼上两位的提问,帮我发现了hello4skyeye中间BUG。事实上原来的hello4skyeye,都是使用arm-elf-tools-20030314编译的,因为编译出来的hello可以运行,所以也没有发现其中的问题。

现在使用arm-elf-tools-20040427编译,就出现错误:Not enough room for program headers, try linking with -N

经过检查发现是hello.lds链接控制脚本中,漏写了一个段.rodata,该段包含只读数据应该放在.text段中。所以修改hello.lds如下所示:
     .text :
        {
                *(.text)
                *(.rodata)
        }

另外Start.S中有一处错误,就是b hello,应该改为bl hello。后者表示跳转至hello执行完后返回。

参考资料:
《Executable and Linking Format(ELF) Specification》

黄敏峰 发表于 2005-3-12 17:24

也给我发一个吧, 谢谢!

mjohh@163.com

黄敏峰 发表于 2005-3-14 10:54

收到! 谢谢

bolla 发表于 2005-3-15 00:18

太好了,感谢楼主!

tropic 发表于 2005-3-15 15:29

非常感谢楼主啊

zweily 发表于 2005-3-17 20:12

关于这个HelloWorld的程序执行流程

根据楼主的教程和原程序的readme,这个Hello4Skyeye的程序我已经能够运行起来了。只是关于这个程序里面的执行流程我有点问题。

我看了start.s文件,里面有
[code:1]
bl hello
b begin
[/code:1]
这一段语句,所以这个程序就不断输出:“helloworld”。
可是我想改成让他只输出一次,于是我就改成这样:
[code:1]
bl hello
@ b begin
[/code:1]
可是这样修改之后没有效果,还是不停地输出,所以我想请教一下这个程序的具体执行流程,为什么会不断输出呢?

另外,我调试的时候看了一下编译出来的汇编代码,发现程序的最后总有这么一句指令:
[code:1]
tsteq r0, r0
[/code:1]
我想问问这句指令到底怎么会编译出来的呢,原程序的.s文件和.c文件都没有相对应的指令阿。

新手提问,希望大家多多指教。 :wink:

zweily 发表于 2005-3-19 14:58

难道置顶贴里的问题没人关心的吗? :shock:

shang79 发表于 2005-3-19 16:17

不好意思,这段时间我在忙另外一个项目。虽然我这次没有调试Hello4Skyeye,但我想还是可以回答你的第一个问题。

Hello4Skyeye结尾并没有终止语句,如果把b begin注释去。Skyeye运行的时候,运行到Hello4Skyeye的结尾并不会停止,而是继续往下执行。下面的指令因为不在Hello4Skyeye的代码段中,所以情况就难以预料了。

根据经验,后面未放代码的地方的指令往往是将程序指令寄存器重新置为0。所以这时程序会调转到0地址开始执行。Hello4Skyeye不是加载到0x01000000地址么,当程序执行到0x01000000地址的时候又会重新执行Hello4Skyeye。这样等于是个大循环。

如果你发现更改完的Hello4Skyeye运行是仍然不断输出Helloworld但是输出速度明显慢于未修改前的,那就基本可以断定是我上面所说的原因。

关于第二个问题,我现在只能大概说明一下,不要认为反汇编出来的就都是指令。有时候反汇编会把数据区的数据反汇编为指令。不知道是不是这个原因才显示tsteq r0, r0

如果你能用Skyeye的log功能调试程序,那么第一个问题是很好解决的。

使用SkyEye的log功能调试Hello4SkyEye:

上章介绍了源码级调试Hello4SkyEye的方法,之所以能进行源码级调试,是因为makefile中编译选项有-g参数,hello.lds文件中有和debug相关段的输出,并且hello可执行程序是elf格式的。这样SkyEye在装载hello程序的时候,就可以从文件中读取相关的调试信息。

但是很多情况下,SkyEye上运行的操作系统内核并非是ELF格式,那么Skeye就无法进行源码级调试了。这个时候使用串口输出调试信息,是调试内核的一个简单方法。但是在串口初始化之前,是无法使用这个方法调试的。其实使用SkyEye调试内核,有一个非常简单有效的方法,那就是使用SkyEye的log功能。我们可以记录下程序的运行流程,再和程序源码及反汇编代码对照,就可以分析出程序运行的流程和各步指令执行时Skyeye虚拟机的状态,根据这些信息就不难推断错误的原因。现在我们可以用Hello4SkyEye来尝试一下SkyEye这种神奇的功能。

SkyEye的log控制选项的说明如下:

log选项用于控制skyeye输出硬件系统的执行状态信息,包括每次执行指令时的执行指令值、寄存器值、各种硬件状态等。
格式:
log: logon=0|1, logfile=filename, start=number1, end=number2, length=number3
    logon=0|1|2|3,如果值等于0表示不进行记录,如果值等于1表示记录指令和指令地址流,如果值等于2表示记录指令和指令地址和主要寄存器内容,如果值等于3表示记录指令和指令地址和所有的寄存器内容。
    logfile=filename 其值是一个字符串,表示用于记录信息的文件名
    start=number1 其值是一个>=0的十进制整数,表示系统执行到第number1条指令时开始进行记录
    end =number2其值是一个>=0的十进制整数,表示系统执行到第number2条指令时停止记录
    length =number3其值是一个>=0的十进制整数,表示只记录系统最近执行的number3条指令时的信息

这里我们把skyeye.conf文件的最后一行改为:

log: logon=2, logfile=./sk1.log, start=0, end=200000

再次运行skyeye hello后,使用Ctrl+C;quit指令退出SkyEye后,就可以在当前目录下的sk1.log中看到hello程序执行的指令流,和每步各主要寄存器的值。

sk1.log的59行到64行如下所示:

N 3b :p 1000044,i e2822001,R 100005c,fffd001c,9,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3c :p 1000048,i e3520009,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3d :p 100004c,i e5813000,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3e :p 1000050,i dafffffa,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 3f :p 1000054,i e91ba800,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,......
N 40 :p 1000010,i eafffffa,R 100005c,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,......


现在就要说明log表与文件源码的对照技巧了。打开hello.s文件,该文件是make时,使用"objdump -xS hello"指令产生的反汇编文件。其中部分如下所示:

for(i=0;i<10;i++)
1000038: e3a02000 mov r2, #0 ; 0x0
100003c: e59f0014 ldr r0, [pc, #20] ; 1000058 <hello+0x38>
{
      * paddr=hellostr[i];
1000040: e7d03002 ldrb r3, [r0, r2]
1000044: e2822001 add r2, r2, #1 ; 0x1
1000048: e3520009 cmp r2, #9 ; 0x9
100004c: e5813000 str r3, [r1]
1000050: dafffffa ble 1000040 <hello+0x20>
      return;
}
1000054: e91ba800 ldmdb fp, {fp, sp, pc}


从log表中可以看出在执行了0x3b步指令后,程序的指令地址是0x1000044,指令内容是0xe2822001。再看反汇编表,0x1000044地址的指令正是0xe2822001,对应的汇编代码是“add r2, r2, #1”,程序正运行在hello函数中的for循环中。

可以从反汇编表的下面两步(0x1000044,0x1000048)

    add r2,r2, #1;
    cmp r2, #9

两句指令看出,计数器i就是寄存器r2。然后看log表中第0x3b步,此时r2=9,这说明hello函数的for循环已经执行了9次,现在正在执行第10次。下步0x3c的时候r2就是0xa(10)了,这正是执行了add r2, r2, #1的结果。这时执行cmp r2,#9判断语句显然r2>9,程序就不再循环而是接着执行下面三步(0x100004c,0x1000050,0x1000054)

   str r3,[r1];
   ble 1000040;
   ldmdb fp, {fp, sp, pd}。

这些指令的执行效果就是退出循环,hello函数返回。可以看到log表结果与此相符,第0x40步的时候,程序跳转到0x1000010处执行了。

从上面的分析可以看出既便不使用skyeye源码级调试的方法,我们也可以通过log表和反汇编表,看出程序运行的流程和关键处的寄存器值,如果发生错误,就可以通过流程变化和寄存器的值分析错误的原因。

zweily 发表于 2005-3-19 21:56

呵呵,真是要谢谢楼主了,回帖很详细,很有价值。明天我去试试看log功能调试。

楼主真是热心人! :wink:

zweily 发表于 2005-3-19 21:58

[quote:680d2d4e5d="shang79"]
如果你发现更改完的Hello4Skyeye运行是仍然不断输出Helloworld但是输出速度明显慢于未修改前的,那就基本可以断定是我上面所说的原因。
[/quote]

补充一下,观察到的现象的确如此的。

iolinux 发表于 2005-3-22 10:52

我是用户,为何看不到源码的链接,
谁可以给我一个?iolinux@163.com  

3q先

zweily 发表于 2005-3-22 13:02

楼上的,已经给你发了。

你是不是没有登陆呢?
先登陆后再看楼主的帖子应该就能看到的。

zweily 发表于 2005-3-22 18:19

继续我的问题

今天按照楼主说的方法用了一下log调试功能,只是那个logon=2的情况下,前两项是指令地址和指令,这个看的明白,可是后面记录的那些主要寄存器有哪些呢?顺序是什么样的呢?

我先贴一下部分代码和log文件:

这里是我的start.s文件:
[code:1]
begin:

        @set up irq stack

        mov         r0, #0xd2                @ make irq mode with all irqs disabled

        msr         cpsr, r0

        ldr         sp, =irq_stack           @ set sp_irq = irq_stack
        bl        hello

        @b        begin
               

.data

        .align  4

irq_stack:

        .space        4096
[/code:1]

可以看到这里我还是把那句调到begin的给注释掉了。

下面是编译后的那个hello.s的反汇编文件:
[code:1]
01000000 <begin>:
1000000:        e3a000d2         mov        r0, #210        ; 0xd2
1000004:        e129f000         msr        CPSR_all, r0
1000008:        e59fd000         ldr        sp, [pc, #0]        ; 1000010 <begin+0x10>
100000c:        eb000000         bl        1000014 <hello>
1000010:        01002000         tsteq        r0, r0
[/code:1]
这一段是对应前面那个start.s的代码。下面部分是hello函数中return的部分:
[code:1]
    return;       
}
1000048:        e91ba800         ldmdb        r11, {r11, sp, pc}
100004c:        01000050         tsteq        r0, r0, asr r0
1000050:        6c6c6568         stcvsl        5, cr6, [r12], -#416
1000054:        726f776f         rsbvc        r7, pc, #29097984        ; 0x1bc0000
1000058:        Address 0x1000058 is out of bounds.
[/code:1]

下面是那个log文件的一部分:
[code:1]
N 3a :p 1000034,i e7d03002,R 1000050,fffd001c,9,6c,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,100003c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3b :p 1000038,i e2822001,R 1000050,fffd001c,9,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000040,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3c :p 100003c,i e3520009,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000044,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3d :p 1000040,i e5813000,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000048,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3e :p 1000044,i dafffffa,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,100004c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 3f :p 1000048,i e7ffdefe,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000050,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000030,T 0,L e2822001,D e7d03002,
N 40 :p 1000048,i e91ba800,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000050,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000048,T 0,L 6c6c6568,D 1000050,
N 41 :p 1000010,i 1002000,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,1000018,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000048,T 0,L 6c6c6568,D 1000050,
N 41 :p 1000010,i 1002000,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,1000018,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000010,T 0,L e92dd800,D e1a0c00d,
N 42 :p 1000014,i e1a0c00d,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,100001c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000010,T 0,L e92dd800,D e1a0c00d,
N 42 :p 1000014,i e1a0c00d,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,100001c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 43 :p 1000018,i e92dd800,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1002000,1000010,1000020,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 44 :p 100001c,i e24cb004,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,0,1002000,1001ff0,1000010,1000024,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 45 :p 1000020,i e3e01bbf,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000028,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 46 :p 1000024,i e2411e3e,R 1000050,fffd03ff,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,100002c,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 47 :p 1000028,i e2411003,R 1000050,fffd001f,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000030,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
N 48 :p 100002c,i e7ffdefe,R 1000050,fffd001c,a,64,0,0,0,0,0,0,0,1001ffc,1002000,1001ff0,1000010,1000034,C d2,S 0,0,0,0,0,0,0,M 12,B 2,E 0,I 0,P 1000014,T 0,L e24cb004,D e92dd800,
[/code:1]

下面是这段log里相关的一部分代码:
[code:1]
01000014 <hello>:
1000014:        e1a0c00d         mov        r12, sp
1000018:        e92dd800         stmdb        sp!, {r11, r12, lr, pc}
100001c:        e24cb004         sub        r11, r12, #4        ; 0x4
void hello(void)
{       
        int i;
        char * hellostr="helloworld";
        long* paddr=(long*)0xfffd001c;
1000020:        e3e01bbf         mvn        r1, #195584        ; 0x2fc00
1000024:        e2411e3e         sub        r1, r1, #992        ; 0x3e0
1000028:        e2411003         sub        r1, r1, #3        ; 0x3
[/code:1]

根据log文件可以看到在1000048执行了2次,而且第一次的指令是e7ffdefe,不是反汇编对应的指令,而后面那条1000048才是。之后就跳到了1000010,同样执行了2次,然后就又顺序执行到了hello里面。

这个过程就是我上次的问题所在了。看了log之后,还是没想明白,呵呵
:oops:

麻烦老大继续来解释解释吧。  :)

另外我还有个问题,因为不了解GNU的汇编,所以想问问那下面终止语句是什么?
网上搜到了GNU AS的参考手册,可是没有找到该指令。

所以我想问问有什么可以学学GNU AS的,麻烦楼主继续指点~~~~ :roll:

shang79 发表于 2005-3-22 23:03

呵呵,我Skyeye执行的log怎么没有重复的记录?你用的Skyeye版本是多少的?
如果想要系统学习Skyeye,请看看下面这本书,会非常有帮助。
《源码开放得嵌入式系统软件分析和实践--基于skyeye和ARM开发平台》
另外,GNU AS讲的只是AT&T的汇编语法,真正的ARM汇编指令还是要查ARM开发书籍。这个和GNU AS是两回事

pace 发表于 2005-3-23 16:16

hello4skyeye 这个程序在哪呀?

刚开始学习skyeye,我下了skyeye.bin,但是请问上面提到的hello4skyeye的源码在什么?

zweily 发表于 2005-3-24 00:16

[quote:fc7807dea3="shang79"]呵呵,我Skyeye执行的log怎么没有重复的记录?你用的Skyeye版本是多少的?
[/quote]
最新的那个吧,好象是0.8.8?具体忘了,明天看看,呵呵。
我这个是用skyinsight加了断点调试的,让他走了一次hello函数,再进入第二次后,我就把它退出了。
我就是好奇为什么会有重复记录呢,呵呵。


[quote:fc7807dea3="shang79"]
如果想要系统学习Skyeye,请看看下面这本书,会非常有帮助。
《源码开放得嵌入式系统软件分析和实践--基于skyeye和ARM开发平台》
[/quote]
已经在网上订了这本书了,只是还没送来,呵呵 :)


[quote:fc7807dea3="shang79"]
另外,GNU AS讲的只是AT&T的汇编语法,真正的ARM汇编指令还是要查ARM开发书籍。这个和GNU AS是两回事[/quote]
哦,知道了。
只是在那下面开发,编译器是只支持GNU AS的呢?还是同样支持ARM指令的呢?是不是可以用ARM汇编指令重写你的那个start.s文件呢?

呵呵,问题较多,还忘多多指教~~ :wink:

zweily 发表于 2005-3-24 00:17

Re: hello4skyeye 这个程序在哪呀?

[quote:d102efd4b3="pace"]刚开始学习skyeye,我下了skyeye.bin,但是请问上面提到的hello4skyeye的源码在什么?[/quote]

源码见本贴的顶楼,呵呵 8)

页: [1] 2 3 4

Powered by Discuz! Archiver 6.1.0F  © 2001-2007 Comsenz Inc.