This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Adding structured control flow to any assembler

If your assembler doesn't already have structured control-flow, e.g. _IF _ELSE _ENDIF _UNTIL _WHILE etc (not to be confused with conditional assembly)
then here's how to add it yourself for free, without needing access to the assembler's source code.

http://dkeenan.com/AddingStructuredControlFlowToAnyAssembler.htm

Structured control-flow eliminates the need for most explicit jumps, and the labels they jump to, and thereby makes your code more readable and maintainable.

-- Dave Keenan

  • I'm not sure what this article is about.  Apparently, you use Forth to somehow preprocess the assembly code.  This Forth step converts the macros into valid assembly for the target processor.  It doesn't give a step by step description of how to actually make it work.

    -George

  •  

    Georgem said:
    I'm not sure what this article is about.  Apparently, you use Forth to somehow preprocess the assembly code.  This Forth step converts the macros into valid assembly for the target processor.  It doesn't give a step by step description of how to actually make it work.

    Hi George,

    Perhaps you're having trouble believing it could be this simple. No Forth is required. You don't need to know anything about Forth. The only reason I mention Forth is to acknowledge the source of the method. I have already translated the Forth definitions into assembler macros for you. No preprocessing is required. Just put the provided assembler macros (and condition code constants) into an include file, then you can write structured assembler like the right-hand examples at the start of the article.

    Of course the supplied macros and constants are for a specific assembler (IAR Workbench) and a specific target (MSP430), but very little work should be required to adapt it to other assemblers and targets.

    I will update the article to try to make this clearer. Thanks for your response. Any other comments to help me improve the article would be gratefully received.

    BTW, I didn't post my message to this forum. I posted it to another TI E2E Community forum in which I saw assembler mentioned, but it was moved to this forum.

    -- Dave

  • David,

      This was fantastically interesting when I came across it yesterday, as I had been beating the bushes looking for exactly the kind of macro set you define here. I'm very eager to use structured assembler with the MSP430 as I'd done with the 68k years ago.  However, after studying the assembler manual and experimenting a bit it appears that the TI tools are not up to the task of supporting anything like what you describe (which I assume are using different 430 tool chain). The asm430 tool that comes with CCSv5 on Linux does not appear to allow redefinition of equates (or even forward references), let alone direct control of the origin. I'd sincerely like to find out I'm wrong about this or find a free alternative, but as things stand it appears impossible to implement structured control-flow with the CCS assembler. (The manual I'm using for reference is "slau131e.pdf" aka "MSP430 Assembly Language Tools v 3.3")

      I'm not afraid to implement this mechanism myself with a custom preprocessor that generates assembler acceptable to the (feeble!) asm430 tool. But it would have been so much easier to use macros, especially when using the CCS IDE.

    -- Pete Soper

  • Hi Pete,

    Great to hear from you. Yes, I'm sorry I overstated the case somewhat when I said "any" assembler. At the time I was not aware of the limitations of the GNU assembler "as", which does not allow you to move the assembly address backward. The GNU assembler does have a .org directive, but it can only be used to move _forward_. And now you have alerted me to the same problem with the CCS assembler, which doesn't even _have_ a .org directive. It may be that the CCS assembler is based on an old (pre .org) version of the GNU assembler. The lack of forward references should not be a problem for my method, and it appears you may be able to redefine assembler variables using the .eval directive, but without the ability to move backwards and forwards in the output file (i.e. without a bidirectional .org directive) the method is dead.

    It seems that these assemblers were designed to take the output of a C-compiler, not a human.

    But I'm happy to tell you there is a free alternative for assembly-language-only projects (and those with only a small amount of C). The free "kickstart" edition of the IAR Workbench allows unlimited code generation from assembler (but limited code generation from C) . That's what the macros in my article are written for.

    Yes, you could write a preprocessor to implement these structured-control-flow words at the textual level. The macros could be turned directly into C code to manipulate the source text. Instead of pushing and popping assembly addresses to and from the control-flow stack, you'd be pushing and popping source-code line numbers. And instead of ORing bit-fields to assemble jump instructions you'd be concatenating strings to generate their assembler source. You might need to represent the source text as an array of pointers to strings (lines), so you can move backwards and forwards, to allow you to go back and fill in lines that are left blank by _IF.

    I don't understand why someone familiar with the source code of the GNU assembler hasn't made .org work backwards. But I seem to remember a comment in the manual to the effect "If you think it needs fixing, fix it yourself". However I'm not familiar with its source or how it works, and I only have one lifetime.

    Please let us know what you end up doing.

    -- Dave Keenan

  • Hi Dave,

       Thanks for the quick reply. I'd seen various flavors of tools for the MSP430 and settled on the CCS v5 because of a strong preference for Linux. I will try out the Kickstart IAR, though. If it will run the MSP430 Launchpad USB interface from within VirtualBox on my Linux system (with a Windows XP instance in the VM) then that may be the way to go. The 4kb C code limit is no problem at this point (it will be amusing to see how they enforce this).

      After yesterday's posting I wrote  a Ruby script that takes assembler with your _IF/_ELSE et al directives embedded and puts out something asm430 is happy with. I've got all the statements implemented and just have to fill in some of the condition code cases and then make it pretty. This exercise brought back more clear memories of the 68k macro set I used around 1983. I can't recall if it was part of the 68k assembler that came with  68K CP/M or if was something we got separately.  However "Easy68k", which appear to have started life in 1986, seems to have copied the same features and then extended them. I was working right down the road from NC State, which seems to be where most of Easy68k started life.

      But the MSP430 ISA is so incredibly, deliciously regular that a person like me could go a bit overboard with extending the Ruby script to support a range of simple operations and maybe I'd never get around to writing C. That would take care of the 4k limit. :-)

    Best Regards,

    Pete

    PS (The Easy68k info is at http://easy68k.com but *be careful* not to click on the embedded ads to the right, especially the ones that invite you to "download".)

  • I have just finished writing part 2 of Adding Structured Control Flow To Any* Assembler.

    It deals with how to implement short-circuit conditionals, case/switch statements and counted loops.

    http://dkeenan.com/AddingStructuredControlFlowToAnyAssembler2.htm

  • I have updated part 2 to include a far more readable set of macros for writing structured short-circuit conditionals in assembly language, that do not require overlapping structures.

    http://dkeenan.com/AddingStructuredControlFlowToAnyAssembler2.htm