有哪些技术可用于 8051 汇编语言的内存优化?

发布于 2024-07-09 20:52:40 字数 66 浏览 8 评论 0原文

我需要优化代码以为一些新代码腾出空间。 我没有空间进行所有更改。 我无法使用代码库切换(80c31 与 64k)。

I need to optimize code to get room for some new code. I do not have the space for all the changes. I can not use code bank switching (80c31 with 64k).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

累赘 2024-07-16 20:52:40

您在这里并没有真正给出太多内容,但您可以考虑两个主要级别的优化:

微观优化:
例如。 异或 A 代替 MOV A,0
Adam 之前已经很好地介绍了其中的一些内容。

宏观优化:
查看程序的结构、使用的数据结构和算法、执行的任务,并认真思考如何重新排列甚至删除这些内容。 是否有整块代码实际上没有被使用? 您的代码是否充满了用户从未看到的调试输出语句? 是否有特定于单个客户的功能可以从一般版本中删除?

为了很好地处理这个问题,您需要弄清楚您的内存在哪里被耗尽。 链接器图是一个很好的起点。 宏观优化是取得重大胜利的地方。

顺便说一句,您可以认真地尝试使用良好的优化 C 编译器重写部分代码。 您可能会对代码的紧凑程度感到惊讶。 真正的汇编高手也许能够改进它,但它很容易比大多数编码员更好。 大约 20 年前,我使用了 IAR ,并且它让我大吃一惊。

You haven't really given a lot to go on here, but there are two main levels of optimizations you can consider:

Micro-Optimizations:
eg. XOR A instead of MOV A,0
Adam has covered some of these nicely earlier.

Macro-Optimizations:
Look at the structure of your program, the data structures and algorithms used, the tasks performed, and think VERY hard about how these could be rearranged or even removed. Are there whole chunks of code that actually aren't used? Is your code full of debug output statements that the user never sees? Are there functions specific to a single customer that you could leave out of a general release?

To get a good handle on that, you'll need to work out WHERE your memory is being used up. The Linker map is a good place to start with this. Macro-optimizations are where the BIG wins can be made.

As an aside, you could - seriously- try rewriting parts of your code with a good optimizing C compiler. You may be amazed at how tight the code can be. A true assembler hotshot may be able to improve on it, but it can easily be better than most coders. I used the IAR one about 20 years ago, and it blew my socks off.

听闻余生 2024-07-16 20:52:40

使用汇编语言,您必须手动优化。 以下是一些技巧:

注意:IANA8051P(我不是 8501 程序员,但我在其他 8 位芯片上进行了大量的汇编)。

仔细检查代码,查找任何重复的位,无论如何小并使其发挥作用。

了解一些更不寻常的指令,看看是否可以使用它们来优化,例如。 一个不错的技巧是使用 XOR A 来清除累加器而不是 MOV A,0 - 它可以节省一个字节。

另一个巧妙的技巧是,如果您在返回之前调用一个函数,只需跳转到它,例如,而不是:

CALL otherfunc
RET

Just do:

JMP otherfunc

始终确保尽可能执行相对跳转和分支,它们比绝对跳转使用更少的内存。

这就是我暂时能想到的一切。

With assembly language, you'll have to optimize by hand. Here are a few techniques:

Note: IANA8051P (I am not an 8501 programmer but I have done lots of assembly on other 8 bit chips).

Go through the code looking for any duplicated bits, no matter how small and make them functions.

Learn some of the more unusual instructions and see if you can use them to optimize, eg. A nice trick is to use XOR A to clear the accumulator instead of MOV A,0 - it saves a byte.

Another neat trick is if you call a function before returning, just jump to it eg, instead of:

CALL otherfunc
RET

Just do:

JMP otherfunc

Always make sure you are doing relative jumps and branches wherever possible, they use less memory than absolute jumps.

That's all I can think of off the top of my head for the moment.

不甘平庸 2024-07-16 20:52:40

抱歉我来晚了,但我曾经遇到过完全相同的问题,并且它成为一个不断出现的重复问题。 就我而言,该项目是一部电话,采用 8051 系列处理器,我已经完全用尽了 ROM(代码)内存。 我不断地想起这个问题,因为管理层不断要求新功能,所以每个新功能都变成了一个两步过程。 1)优化旧的东西以腾出空间2)实现新功能,用完我刚刚腾出的房间。

有两种优化方法。 战术和战略。 战术优化通过微观优化思想一次节省几个字节。 我认为你需要战略优化,其中包括对你的做事方式进行更彻底的重新思考。

我记得的一些事情对我有用,也可能对你有用;

查看代码必须执行的操作的本质,并尝试提炼出一些非常强大、灵活的原始操作。 然后重建您的顶级代码,以便它除了调用原语之外根本不执行任何低级别操作。 理想情况下使用基于表格的方法,您的表格包含以下内容: 输入状态、事件、输出状态、原语......换句话说,当事件发生时,在表中的单元格中查找当前状态下的该事件。 该单元格告诉您要更改为什么新状态(可选)以及要执行什么原语(如果有)。 您可能需要针对不同层/子系统的多组状态/事件/表/基元。

这种方法的众多好处之一是,您可以将其视为针对您的特定问题构建自定义语言,其中您可以非常有效地(即使用最少的额外代码)简单地通过修改表来创建新功能。

抱歉,我迟到了几个月,而且您可能没有时间做这么激进的事情。 据我所知,您已经在使用类似的方法了! 但有一天我的回答可能会帮助其他知道的人。

Sorry I am coming to this late, but I once had exactly the same problem, and it became a repeated problem that kept coming back to me. In my case the project was a telephone, on an 8051 family processor, and I had totally maxed out the ROM (code) memory. It kept coming back to me because management kept requesting new features, so each new feature became a two step process. 1) Optimize old stuff to make room 2) Implement the new feature, using up the room I just made.

There are two approaches to optimization. Tactical and Strategical. Tactical optimizations save a few bytes at a time with a micro optimization idea. I think you need strategic optimizations which involve a more radical rethinking about how you are doing things.

Something I remember worked for me and could work for you;

Look at the essence of what your code has to do and try to distill out some really strong flexible primitive operations. Then rebuild your top level code so that it does nothing low level at all except call on the primitives. Ideally use a table based approach, your table contains stuff like; Input state, event, output state, primitives.... In other words when an event happens, look up a cell in the table for that event in the current state. That cell tells you what new state to change to (optionally) and what primitive(s) (if any) to execute. You might need multiple sets of states/events/tables/primitives for different layers/subsystems.

One of the many benefits of this approach is that you can think of it as building a custom language for your particular problem, in which you can very efficiently (i.e. with minimal extra code) create new functionality simply by modifying the table.

Sorry I am months late and you probably didn't have time to do something this radical anyway. For all I know you were already using a similar approach! But my answer might help someone else someday who knows.

世界如花海般美丽 2024-07-16 20:52:40

在不堪重负的部门中,您还可以考虑压缩部分代码,并仅保留在任何特定时间点主动使用的某些部分进行解压缩。 我很难相信压缩/解压缩系统所需的代码会足够小,占 8051 微小内存的一部分,因此值得这样做,但在稍大的系统上却创造了奇迹。

另一种方法是转向字节码格式或某些状态机工具输出的表驱动代码——让机器理解您的应用程序正在做什么并生成完全难以理解的实现可能是节省成本的好方法。 room :)

最后,如果代码确实是用 C 语言编译的,我建议使用一系列不同的选项进行编译,看看会发生什么。 另外,我早在 2001 年就为 ESC 写了一篇关于紧凑 C 编码的文章这仍然是相当流行的。 请参阅该文本以了解小型机器的其他技巧。

In the whacked-out department, you could also consider compressing part of your code and only keeping some part that is actively used decompressed at any particular point in time. I have a hard time believing that the code required for the compress/decompress system would be small enough a portion of the tiny memory of the 8051 to make this worthwhile, but has worked wonders on slightly larger systems.

Yet another approach is to turn to a byte-code format or the kind of table-driven code that some state machine tools output -- having a machine understand what your app is doing and generating a completely incomprehensible implementation can be a great way to save room :)

Finally, if the code is indeed compiled in C, I would suggest compiling with a range of different options to see what happens. Also, I wrote a piece on compact C coding for the ESC back in 2001 that is still pretty current. See that text for other tricks for small machines.

终遇你 2024-07-16 20:52:40

1) 尽可能将变量保存在 Idata 中而不是 xdata
2)看看你的Jmp语句——利用SJmp和AJmp

1) Where possible save your variables in Idata not in xdata
2) Look at your Jmp statements – make use of SJmp and AJmp

七月上 2024-07-16 20:52:40

我假设您知道它不适合,因为您编写/遵守并收到“内存不足”错误。 :) 看来答案非常准确地解决了您的问题; 缺少代码示例。

然而,我想推荐一些额外的想法;

  1. 确保所有代码确实
    正在使用——代码覆盖率测试? 一个
    未使用的潜艇是一个巨大的胜利——这是一个
    艰难的一步——如果你是原创者
    作者,这可能更容易——(好吧,也许):)
  2. 确保“验证”的水平
    和初始化——有时我们
    有过度热心的倾向
    确保我们已经初始化
    变量/内存,果然
    确实如此,我们有多少次
    被它咬了。 没有说不要
    初始化(废话),但是如果我们这样做
    记忆的移动,目的地
    不需要首先归零--
    这与

    1 --

  3. 评估新功能 -- 可以
    现有的子系统将得到增强以覆盖
    两者都有功能,或者可能是
    现有功能已被替换?
  4. 分解大代码,如果其中一部分
    大代码可以节省创建一个新的
    代码很少。

或者也许现在有关于硬件版本 2.0 的争论......:)

问候

I assume you know it won't fit because you wrote/complied and got the "out of memory" error. :) It appears the answers address your question pretty accurately; short of getting code examples.

I would, however, recommend a few additional thoughts;

  1. Make sure all the code is really
    being used -- code coverage test? An
    unused sub is a big win -- this is a
    tough step -- if you're the original
    author, it may be easier -- (well, maybe) :)
  2. Ensure the level of "verification"
    and initialization -- sometimes we
    have a tendency to be over zealous
    in insuring we have initialized
    variables/memory and sure enough
    rightly so, how many times have we
    been bitten by it. Not saying don't
    initialize (duh), but if we're doing
    a memory move, the destination
    doesn't need to be zero'd first --
    this dovetails with

    1 --

  3. Eval the new features -- can an
    existing sub be be enhanced to cover
    both functions or perhaps an
    existing feature replaced?
  4. Break up big code if a piece of the
    big code can save creating a new
    little code.

or perhaps there's an argument for hardware version 2.0 on the table now ... :)

regards

暮倦 2024-07-16 20:52:40

除了已经提到的(或多或少)明显的优化之外,这里还有一个非常奇怪(并且几乎不可能实现)的优化:代码重用。 对于代码重用,我指的不是正常的重用,而是 a) 将代码重用为数据或 b) 将代码重用为其他代码。 也许您可以创建一个 lut (或任何静态数据),它可以由 asm 十六进制操作码表示(这里您必须查看哈佛与冯诺依曼架构)。

另一种方法是在您以不同的方式处理代码时,通过赋予代码不同的含义来重用代码。 这是一个例子来阐明我的意思。 如果代码的字节如下所示:地址 X 处的 AABCCCDDEEFGGHH,其中每个字母代表一个操作码,想象一下您现在将跳转到 X+1。 也许您会获得完全不同的功能,其中现在由空格分隔的字节形成新的操作码:ABC CCD DE EF GH。

但要注意:这不仅很难实现(也许是不可能的),而且维护起来也很可怕。 因此,如果您不是演示代码(或类似的异国情调),我建议使用已经提到的其他方法来保存内存。

Besides the already mentioned (more or less) obvious optimizations, here is a really weird (and almost impossible to achieve) one: Code reuse. And with Code reuse I dont mean the normal reuse, but to a) reuse your code as data or b) to reuse your code as other code. Maybe you can create a lut (or whatever static data) that it can represented by the asm hex opcodes (here you have to look harvard vs von neumann architecture).

The other would reuse code by giving code a different meaning when you address it different. Here an example to make clear what I mean. If the bytes for your code look like this: AABCCCDDEEFFGGHH at address X where each letter stands for one opcode, imagine you would now jump to X+1. Maybe you get a complete different functionality where the now by space seperated bytes form the new opcodes: ABC CCD DE EF GH.

But beware: This is not only tricky to achieve (maybe its impossible), but its a horror to maintain. So if you are not a demo code (or something similiar exotic), I would recommend to use the already other mentioned ways to save mem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文