用汇编写入可以减少代码大小和执行时间。但是,假如我有足够的记忆和足够的时间。我可以只使用C代码并引导设备吗?我的意思是,从开机直接运行C代码。我特别感兴趣的是ARM处理器。为什么所有的ARM bootloader都有汇编代码?
回答
我也不知道确切的答案。我只是提出一些我能想到的(减去内存和效率)的原因:
- 该代码是非常具体的设备,无需进行编译和其他地方运行
- 使用特殊指令
(?) - 启动加载程序运行时的状态与正常程序(?)(堆栈,堆)不同
声明:此答案可能包含错误信息。这里不要重视任何事情。
引导加载程序负责在设备启动时对其进行初始化。在这一点上,汇编器没有别的可用。汇编器部分通常保持尽可能小,并负责初始化系统,以便操作系统的一部分和例如最小的C运行时间可以加载到内存中并执行,并且在此之后其他初始化任务可以使用例如C.
有些链接可能会有所帮助:
希望这是有帮助的。
其实你可以为ARM的Cortex-M3 microcontrollers做一个C-only固件。因为它的向量表包含栈指针的条目,所以它的值将被处理器初始化,并且您可以使用直接从重置开始的编译代码。您仍然需要设置外设并初始化C库环境,但不必在汇编器中完成。 Cortex-M3的同时自动保存在中断处理程序入口易失性寄存器,使他们也可以直接在C.
也就是说,大多数编译器厂商仍然提供用汇编语言编写的启动,因为它提供了最大程度的控制写入。
我想添加(只是为了清楚),矢量表可以是C数组,也可以是Cortex-M3。只是使用...'__attribute __((section(“。isr_vector”)))VectorFunc g_pfnVectors [] = {...};' – 2013-05-05 00:13:43
如前所述,Cortex-M3的是特殊的,会允许这样的事情,还好有一个例外,你仍然需要一些ASM或其他一些魔法打造量表调用C代码。
一般是没有,需要回答一些组件。处理器是通用的,他们通常不知道你为程序和数据以及堆栈设置了什么地址空间,寄存器,特别是堆栈指针,通常被初始化为一些已知的值,例如零。处理器一般都知道有一个启动序列,要么是有一个地址开始执行,要么是一个地址,在这个地址找到一个开始执行的地址。该地址表,一个用于复位,一个用于中断等,由引导代码的程序员放置在那里,虽然可以用C来管理,不值得花费精力,但更容易编写几行asm来构建该向量表。 (这是皮层-m的情况)
所以至少你需要设置一个堆栈指针,然后分支到条目C代码,从那里你可以逃脱运行C.现在,如果这是一个arm并不是cortex-m,那么你有多个堆栈来设置(如果你想使用中断,处理故障等),你必须使用特定的asm指令来执行该设置,所以需要asm,real或inline 。
如果您习惯使用.data或期望.bss为零,则必须执行此操作,但某些代码必须将bss清零并准备.data。通常你的系统(即使是你的台式机/笔记本电脑)将从闪存启动,如果你有.data,.data需要在闪存中,但希望被读/写,所以你需要将这些数据从闪存复制到它的家园在内陆,好吧,你需要先运行并运行(见下文)来做到这一点。
不是在过去的美好时光,但肯定今天与德拉姆你无法打开并开始使用内存,有很多代码需要dram和运行。是的,这段代码是用C语言编写的,可能不是asm(尽管出于性能方面的原因,asm可能被用来利用特定的指令,而不一定会让C编译器为你生成)。
所以你有一个不同的场景一般,不一定具体到手臂。我将列出一些但不是每个细微差别
1)你有一个系统使用sram或内部ram,不需要初始化,你没有使用.data,你的代码不会假定.bss已被清零。通常情况下,最小化是初始化堆栈指针并分支到C入口点(main,或任何你称之为的)。
2)你有一个系统使用sram或内部ram,不需要初始化,你正在使用.data,你希望在你的C代码开始之前就存在(对于C程序员来说很典型)和.bss在你的C代码开始之前为零(也是典型的,但幸好gcc开始抱怨这样做的代码)。由于您的C代码在这种情况下期望在C代码运行之前准备好这些东西,因此将.bss归零并将.data从闪存复制到RAM会发生在asm中。这是你最常见的场景,请查看许多针对不同处理器的crt0.s例程,这是常用主题,设置堆栈指针,零bss,将.data分支复制到main。 3)你有一个系统有一些内部的sram,不需要初始化,但你期望使用的主存是dram。这是两个步骤,您的第一个引导加载程序仍然需要设置堆栈指针,根据您的首选项可选地设置零.bss和复制.data,然后分支到第一个引导加载程序的入口点。这个引导程序将启动dram系统。现在,该引导加载程序可以选择复制.data和零.bss(现在可以在C中),然后转到主引导加载程序入口点/函数,该入口函数需要并使用较大的主内存。
4)你有一个微处理器的x86处理器,你需要在启动时修补微代码,我没有这方面的个人知识,但会假设你应该使用的指令数量有限,因为你正在改变微编码的一些,或者你复制到一些内存然后翻转一下,它奇迹般地切换补丁,你执行变化,不知道,但我敢打赌,一些组装是必需的。
请记住,许多C库调用都在组装中。所以C是组装的,尤其是手臂。你避免所有的分歧,乘法,模数,浮点数等吗?你从不使用任何字符串函数或复制函数吗?你是否使用C库函数?这很可能是你正在使用的asm,并且不知道它。 memcpy通常是手动调整的,尤其是手臂。如果你在代码中使用结构,编译器可能会抛出memcpys,具体取决于你使用的是什么以及如何使用它们。分而定模。繁殖有时。浮点,通常是asm,即使有fpu也是如此。你确实没有写过这个asm,但是有可能是asm,并且你的引导程序不会没有asm(如果你使用这些库)存在。
你的标题问题,暗示只有一个引导程序的程序集是错误的,引导程序大多不是程序集。几乎总是需要一些组件。
cortex-m是一个独特的野兽,因为它的设计使您不必使用特殊指令或asm来包装中断(或让编译器为您做这件事)。不典型。虽然cortex-m有一个巨大的向量表。好奇你如何用C编写这个表。我有一些想法如何做,但是它对于asm来说更容易,即使asm实际上并不是汇编程序的指令(.word this_handler,.word that_handler) 。至少在传统ARM的32位ARM7指令ARM内核中,您必须设置堆栈并在asm中至少分支到C代码,除非您玩编译器游戏,异常处理程序还需要一点asm,只是几行。我不得不怀疑这个问题的根源。引导加载程序与处理器和附属设备非常紧密地联系在一起,编写引导加载程序的程序员必须能够很方便地使用硬件寄存器等,这意味着对于该处理器的指令集有一定的舒适度。避免引导程序中的所有asm是一个问题。即使使用cortex-m只是因为你可以直接从向量表转换为C代码,你仍然需要验证你使用的编译器符合硬件调用约定,而不仅仅是一些通用的arm调用约定,以确保保留一定范围的寄存器并在返回时使用正确的指令,这意味着对编译器生成的代码进行反汇编和手动/可视化检查,但是在这个级别上,尽管只是阅读,与写入asm相当。
http://github.com/dwelch67我有很多没有操作的嵌入式arm示例系统或引导加载程序,实质上它们是它们自己的引导加载程序,尽管我没有为cortex-m做这个技巧,您可以看到引导加载程序有多简单,需要多少asm。零汇率绝对不是我的目标,所以我没有达到这个极限。 –
- 1. 汇编代码中的.arm是什么?
- 2. ARM汇编代码
- 3. Keil arm startup.s汇编代码
- 4. 了解ARM汇编代码
- 5. 为什么qemu-arm在这个arm汇编代码中反复运行pthread_join?
- 6. ARM汇编 - 一个简单的代码
- 7. 为什么所有的孩子都执行主代码?
- 8. 为什么所有的java代码都打包在类中?
- 9. 这个汇编代码有什么问题,有条件的jmp
- 10. 为什么这个IA32汇编代码有三条leal指令?
- 11. C到arm汇编代码转换
- 12. 这有什么错我的汇编代码
- 13. 用于模拟循环的汇编代码有什么问题?
- 14. 我的汇编代码有什么问题
- 15. arm汇编代码 - 了解cpp源代码的拆卸
- 16. 转换C-代码的ARM Cortex M3汇编代码
- 17. iOS汇编代码
- 18. 有什么JVM汇编器?
- 19. 为什么所有visual studio 2013代码都带有红色背景?
- 20. 这2个汇编代码段有什么区别?
- 21. 这个Linux汇编程序代码有什么错误?
- 22. 无法理解反汇编代码,有什么想法?
- 23. 这个汇编代码有什么问题?
- 24. 以下汇编代码读取文件有什么问题?
- 25. 反编译汇编代码有多难?
- 26. ARM汇编
- 27. ARM汇编调用带有用C
- 28. ARM汇编函数有问题吗?
- 29. 如何将此代码更改为ARM汇编指令?
- 30. 为什么我的findObjectsInBackgroundWithBlock:^中没有执行所有的代码?
我不知道你在问什么。 – leppie