Unravelling汇编语言面条code [英] Unravelling Assembly Language Spaghetti Code

查看:226
本文介绍了Unravelling汇编语言面条code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我继承写的,需要一些改变8051汇编语言10K行的程序。不幸的是它是写在意大利面条code的优良传统。该方案 - 写成一个单独的文件 - 是CALL和LJMP语句(约1200个)的迷宫,具有多个入口和/或出口点的子程序,如果他们能在所有被认定为子程序。所有变量都是全球性的。有评论;有些是正确的。有没有现有的测试,也没有预算的重构。

I've inherited a 10K-line program written in 8051 assembly language that requires some changes. Unfortunately it's written in the finest traditions of spaghetti code. The program--written as a single file--is a maze of CALL and LJMP statements (about 1200 total), with subroutines having multiple entry and/or exit points, if they can be identified as subroutines at all. All variables are global. There are comments; some are correct. There are no existing tests, and no budget for refactoring.

在应用程序中的小背景:code控制在当前国际上部署了一个自动售货机的应用程序的通信枢纽。它同时处理两个串行流(与单独的通信处理器的帮助下),并且可以从不同的供应商交谈多达四个不同的物理设备中,每个。其中一个设备的制造商最近做了更改(是的,我们做出了改变,但软件的完全一样!),这会导致某些系统配置不再工作,并没有兴趣在不改变它(不管它是什么他们并没有改变)。

A little background on the application: The code controls a communications hub in a vending application that is currently deployed internationally. It handles two serial streams simultaneously (with the help of a separate communications processor) and can be talking to up to four different physical devices, each from a different vendor. The manufacturer of one of the devices recently made a change ("Yeah, we made a change, but the software's absolutely the same!") which causes some system configurations to no longer work, and is not interested in unchanging it (whatever it was they didn't change).

该项目最初是由另一家公司,转让给我的客户写的,然后进行修改九年前由一位顾问。无论是原来的公司,也不是顾问,可作为资源。

The program was originally written by another company, transferred to my client, then modified nine years ago by another consultant. Neither the original company, nor the consultant, are available as resources.

,我想出了一个黑客,这似乎工作,但它的丑陋,没有解决的根本原因。如果我有一个更好的了解该计划的,我相信我能解决企业的实际问题。我有一个多星期前的code的冰冻支持结束一个月的舰艇日期。

Based on analysis of the traffic on one of the serial buses, I've come up with a hack, which appears to work, but it's ugly and doesn't address the root cause. If I had a better understanding of the program, I believe I could address the actual problem. I have about one more week before the code's frozen to support an end-of-the month ship date.

原来的问题:我需要了解程序不够好,做出的改变没有破损。有没有人开发的技术与这种混乱的工作?

Original question: I need to understand the program well enough to make the changes without breakage. Has anyone developed techniques for working with this sort of mess?

我在这里看到了一些很好的建议,但我通过时间的限制。不过,我可能会在未来的另一个机会去追求一些行动更多地参与课程。

I see some great suggestions here, but am limited by time. However I may have another opportunity in the future to pursue some of the more involved courses of action.

推荐答案

首先,我会尝试与谁最初开发code或谁至少保持它在我之前,有希望获得足够的信息的人取得联系拿到code的一个基本的了解一般,这样你就可以开始添加有用的注释。

First, I would try to get in touch with those people who originally developed the code or who at least maintained it before me, hopefully getting enough information to get a basic understanding of the code in general, so that you can start adding useful comments to it.

也许你甚至可以找人来形容最重要的API(包括他们的签名,返回值和目的)为code。如果全局状态是由函数修改,这也应作出明确的。同样,启动功能和程序,以及输入/输出寄存器之间进行区分。

Maybe you can even get someone to describe the most important APIs (including their signature, return values and purpose) for the code. If global state is modified by a function, this should also be made explicit. Similarly, start to differentiate between functions and procedures, as well as input/output registers.

您应该让您的雇主很清楚,这信息是必需的,如果他们不相信你,让他们实际上你坐下来在这个code的前面,你描述你应该做的事情你怎么也得做(逆向工程)。在计算和编程具有背景的雇主实际上是在这种情况下有帮助!

You should make it very clear to your employer that this information is required, if they don't believe you, have them actually sit down with you in front of this code while you describe what you are supposed to do and how you have to do it (reverse engineering). Having an employer with a background in computing and programming will actually be helpful in that case!

如果你的雇主没有这样的技术背景,请他带来的另一个程序员/同事解释你的脚步给他,这样做实际上会告诉他,你是认真和诚实的,因为它是一个真正的问题 - 不只是从你的角度来看(确保有谁知道这个项目的同事)

If your employer doesn't have such a technical background, ask him to bring another programmer/colleague to explain your steps to him, doing so will actually show him that you are serious and honest about it, because it's a real issue - not just from your point of view (make sure to have colleagues who know about this 'project').

如果有效可行,我也非常清楚,即承包(或至少是接触)前开发/维护(如果他们不再为你的公司工作,这是)帮助文档这code将是$ p $对必需以切实提高短时间跨度内的code和,以确保它能够更容易地保持在将来。

If available and feasible, I would also make it very clear, that contracting (or at the very least contacting) former developers/maintainers (if they are no longer working for your company, that is) to help document this code would be a pre-requisite to realistically improve the code within a short time span and to ensure that it can be more easily maintained in the future.

强调,这整个情况是由于在previous软件开发过程,而且这些措施将有助于提高code碱基的缺点。所以,在目前形式的code基是一个日益严重的问题,现在无论是做处理这个问题是对未来的一种投资。

Emphasize that this whole situation is due to shortcomings in the previous software development process and that these steps will help improve the code base. So, the code base in its current form is a growing problem and whatever is done now to handle this problem is an investment for the future.

这本身也是很重要的,帮助他们评估和了解您的情况:做你应该现在做的是远离琐碎的,他们应该了解它 - 如果只以正自己的预期(例如关于最后期限和任务的复杂性)。

This in itself is also important to help them assess and understand your situation: To do what you are supposed to do now is far from trivial, and they should know about it - if only to set their expectations straight (e.g. regarding deadlines and complexity of the task).

另外,我个人开始加入单元测试对于那些我理解不够好,这样我可以慢慢开始重构/重写一些code部分。

Also, personally I would start adding unit tests for those parts that I understand well enough, so that I can slowly start refactoring/rewriting some code.

在换句话说,良好的文档和源代码code意见是一回事,但有一个COM prehensive测试套件是另外一个重要的事情,没有人可以现实地期望修改一个陌生的code基无测试关键功能的任何方式建立

In other words, good documentation and source code comments are one thing, but having a comprehensive test suite is another important thing, noone can be realistically expected to modify an unfamiliar code base without any established way of testing key functionality.

鉴于code是10K,我还要考虑分解出子程序到单独的文件,使组件的详细身份,preferably使用访问的包装,而不是全局变量,也直观的文件名。

Given that the code is 10K, I would also look into factoring out subroutines into separate files to make components more identifiable, preferably using access wrappers instead of global variables and also intuitive file names.

,我会去了解一下步骤,通过降低复杂性,进一步提高源$ C ​​$ C的可读性,具有多个入口点子例程(甚至可能是不同的参数签名?)看起来像一个肯定的方式来混淆在code不必要的。

Besides, I would look into steps to further improve the readability of the source code by decreasing the complexity, having sub routines with multiple entry points (and possibly even different parameter signatures?) looks like a sure way to obfuscate the code unnecessarily.

同样,巨大的分程序也可以被重构到较小的,以帮助提高可读性。

Similarly, huge sub routines could also be refactored into smaller ones to help improve readability.

所以,最重要的东西之一,我会考虑这样做将是巨大的分裂子例程来确定使它真正复杂神交code碱基,然后返工那些部分的那些东西,例如有多个进入点,相互调用,而不是不同的子例程。
如果不能因做性能方面的原因,或致电开销,使用宏来代替。

So, one of the very first things, I'd look into doing would be to determine those things that make it really complicated to grok the code base and then rework those parts, for example by splitting huge sub routines with multiple entry points into distinct sub routines that call each other instead. If this cannot be done due to performance reasons or call overhead, use macros instead.

此外,如果它是一个可行的选择,我会考虑,无论是使用C的一个子集,逐步改写采用了更高级语言的code的部分,至少通过比较过度使用组装宏利于规范code碱基,而且还帮助定位潜在的bug。

In addition, if it is a viable option, I would consider incrementally rewriting portions of the code using a more high level language, either by using a subset of C, or at least by making fairly excessive use of assembly macros to help standardize the code base, but also to help localize potential bugs.

如果用C增量改写是一个可行的选择,一种可能的方式上手将是把所有的功能明显成C函数的尸体被-in /复制的开始 - 从汇编文件粘贴,这样就结束与有很多内联汇编的C函数。

If an incremental rewrite in C is a feasible option, one possible way to get started would be to turn all obvious functions into C functions whose bodies are -in the beginning- copied/pasted from the assembly file, so that you end up with C functions with lots of inline assembly.

就个人而言,我也尝试在模拟器/仿真器运行code方便的通过code步骤并希望开始了解的最重要的组成部分(在检查寄存器堆栈使用),一个很好的8051模拟器内置调试器应提供给你,如果你真的要做到这一点主要是你自己的。

Personally, I would also try running the code in a simulator/emulator to easily step through the code and hopefully start understanding the most important building blocks (while examining register and stack usage), a good 8051 simulator with a built-in debugger should be made available to you if you really have to do this largely on your own.

这也将有助于你想出的初始化序列和主循环结构,以及一个调用图。

This would also help you come up with the initialization sequence and main loop structure as well as a callgraph.

也许,你甚至可以找到一个很好的开源80851模拟器,可以轻松地修改,从而自动提供一个完整的调用图,只是做了快速搜索,我发现的 gsim51 ,但也有明显的其他几个选项,各种专用的以及。

Maybe, you can even find a good open source 80851 simulator that can be easily modified to also provide a full callgraph automatically, just doing a quick search, I found gsim51, but there are obviously several other options, various proprietary ones as well.

如果我是你的情况,我甚至会考虑外包修改我的工具来简化这个源$ C ​​$ C工作的努力,即许多sourceforge的项目接受捐赠,也许你可以跟你的老板变成赞助这样的修改。

If I were in your situation, I would even consider outsourcing the effort of modifying my tools to simplify working with this source code, i.e. many sourceforge projects accept donations and maybe you can talk your employer into sponsoring such a modification.

如果没有财政,也许你所提供对应的补丁呢?

If not financially, maybe by you providing corresponding patches to it?

如果您已经使用了专有的产品,你甚至可以使用该软件,并详细说明您的要求,制造商交谈,询问他们是否愿意改善该产品的任何方式,或者他们至少可以公开一个接口允许客户做出这样的自定义(某种形式的内部API,或者甚至简单的胶合脚本)。

If you are already using a proprietary product, you might even be able to talk with the manufacturer of this software and detail your requirements and ask them if they are willing to improve this product that way or if they can at least expose an interface to allow customers to make such customizations (some form of internal API or maybe even simple glue scripts).

如果他们不回应,表明你的雇主已经在想现在用了一段时间不同的产品,并且您是唯一一个坚持特定产品所使用...; - )

If they are not responsive, indicate that your employer has been thinking of using a different product for some time now and that you were the only one insisting on that particular product to be used ... ;-)

如果软件所需的某些I / O硬件和外设,你甚至可能要考虑编写相应的硬件仿真循环在模拟器中运行该软件。

If the software expects certain I/O hardware and peripherals, you may even want to look into writing a corresponding hardware simulation loop to run the software in an emulator.

最后,我知道一个事实,我个人更欣赏定制其他软件来帮助我理解这样的面条code怪物,不是通过code手动步进的过程中,玩模拟器自己,不管我有多少咖啡加仑可以得到的。

Ultimately, I know for a fact that I would personally much more enjoy the process of customizing other software to help me understand such a spaghetti code monster, than manually stepping through the code and playing emulator myself, no matter how many gallons of coffee I can get.

获得一个可用的调用图了一个开源的8051模拟器不应该远远长于说,利用周末(最多),因为它主要是指以寻找CALL运codeS和记录他们的地址(位置和目标) ,让一切都转储到供以后检查的文件。

Getting a usable callgraph out of an open source 8051 emulator should not take much longer than say a weekend (at most), because it mostly means to look for CALL opcodes and record their addresses (position and target), so that everything's dumped to a file for later inspection.

有机会获得一个仿真器的内部实际上也为了找到运$ C $的重复图案是伟大的方式来进一步检查code,例如CS(比如20-50 +),这可能是分解成独立的功能/过程,这实际上可能有助于进一步降低code基地的规模和复杂性。

Having access to an emulator's internals would actually also be great a way to further inspect the code, for example in order to find recurring patterns of opcodes (say 20-50+), that may be factored into standalone functions/procedures, this might actually help decrease the size and complexity of the code base even further.

下一步很可能会检查堆栈和寄存器使用。并确定使用的函数参数类型/大小,以及它们的值范围 - 这样就可以受孕相应的单元测试

The next step would probably be to examine stack and register usage. And to determine the type/size of function parameters used, as well as their value range - so that you can conceive corresponding unit tests.

使用像点/ graphviz的工具,以可视化的初始化序列和主回路本身的结构,将是一个纯粹的喜悦相比,人工手动操作这一切的东西。

Using tools like dot/graphviz to visualize the structure of the initialization sequence and the main loop itself, will be a pure joy compared to doing all this stuff manually.

此外,你会真正有用的数据和文档,可以作为基础,从长远来看更好的文档中结束。

Also, you'll actually end up with useful data and documents that can serve as the foundation for better documentation in the long run.

这篇关于Unravelling汇编语言面条code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆