Why AS Macro Assembler sucks (IMO)

Discussion in 'Discussion & Q&A' started by FireRat, Apr 16, 2018.

  1. FireRat

    FireRat "The grand imitator..." Member

    Oct 31, 2009
    ASS Macro Assembler is so bad, toxic and dangerous to any project, I swear this is the last project where I'd ever use it (and can't get rid of it right now just because, unfortunately, I'd waste a bunch more of time adapting the damn macros and functions, not to mention the workaround for lack of a straight PHASE command in any other assembler, and I'm tired of wasting time for bad reasons).

    To begin, gotta say bye to a particular practice from professional programming, successfully employed in the 16-bit Sonic the Hedgehog games, or even SEGA's official ICD_MARS program: Can't forget to specify branch sizes or address sizes to any of your comands, else many of your manually-specified bxx.s commands are gonna break. Oh, at any random location, because AS doesn't want you find where you forgot it mwahahahaha

    Features and Expression interpretations are both unreliable.
    This won't work:
            move.w    SineTable+($40*2)-16(pc,d0.w),d1
            move.w    SineTable-16(pc,d0.w),d0
    Instead, this will do:
    SineTableCos        = SineTable+($40*2)-16
    SineTableSin        = SineTable-16
            move.w    SineTableCos(pc,d0.w),d1
            move.w    SineTableSin(pc,d0.w),d0
    Checkout the following array: https://i.imgur.com/35MCKLn.png
    Because this loadblock struct is same for all levels, and because AS allows me to reference local labels from other globals, I thought that the "LB_Addr" label along the other locals would make it easier to point to the entries, relative. For instance, if I wanted to point to .bufstart, it would be done through the expression: (LB_Addr.bufstart)-LB_Addr. To what I tried, so far, it isn't possible to arrange it into a Function in any way. Later, I try to build the following, all of them work:
    .tmp3:        set    ((LB_Addr.bufstart)-LB_Addr)
        move.w    #(LB_Addr.bufstart)-LB_Addr,d0
        move.w    #((LB_Addr.bufstart)-LB_Addr),d0
        move.w    #.tmp3,d0
        move.w    #$0016,d0
    However, only the latter, $0016, seemed to work for this command:
    lea    XXX(a2),a2
    This defeats the point. I was already paranoid about the parenthesis, I tried any sorts of expression combinations... but, when Sik tells me to just try with LB_Addr.bufstart-LB_Addr, shit happens:
    Less than $10 bytes away! Less than 5 lines away! no way!

    PHASE command may or not cause an "address overflow" error, for any arbitrary reasons. While working in 32x, so far it has been flawless to arrange base addresses for each 68k bank, with tricks even. It does fine when switching to SH7600 CPU as well. But out of nothing, it trolls agin if switch to Z80UNDOC and set PHASE to $0. After trying everything on my reach, I could only get it to build with !org 0, and then resort to s3p2bin to avoid the ROM's self-overwriting with normal p2bin.
    It looks like I have no option but to keep the sound driver kosinski-compressed!, or go back to normal p2bin, split the Z80 code out and build it as a binary blob, then binclude it at ROM's tree... ?. But I've struggled enough.

    Even with the points described above, I can still expect any random unpredictable surprises on my way!
    If clean code is wanted here, you can't have personal compromises at all. And so far, I think I spent more time struggling with the build bugs than working in the actual game. Need to rush for an important date, such as SAGE or SHC? Have no idea what the hell is breaking your short branches? Can only move your code around until it builds, or add fillers in-between. It works!!, but sucks unbelievably bad.

    Worst of all is, the issues have been reported, Alfred said he's going to fix them, but then I check the newest version hoping the best and... not only The Same build bugs remain there, but there's new bugs introduced!: For instance, the NATIVE Charset macro won't accept more than 3 arguments anymore!! even though the manual still states it can. The list goes on.

    No more frustrations. Too bad it's used in disassemblies, but still, fuck ASS. Fuck it hard.
    Last edited: Apr 16, 2018
  2. TheStoneBanana

    TheStoneBanana The Bananaman Member

    Nov 27, 2013
    The Milky Way Galaxy
    As you so eloquently put it, AS is ASS.
    Natsumi and FireRat like this.
  3. Novedicus

    Novedicus Well-Known Member Member

    Aug 26, 2013
    Another thing in AS(S) I don't particularly like is attempting code generation, especially with labels. I've found how ASM68K can add the contents of a variable to labels (i.e. c = 1, "Label\#c" will generate "Label1") to be extremely useful in this case when I use "rept" statements.

    No matter what I tried in AS, I couldn't do something similar. I may be doing something horribly wrong, but, it's just all been a pain in the ass to me.
    FireRat likes this.
  4. Clownacy

    Clownacy UP - ON - CPU Staff

    Aug 15, 2014
    o baby

    I remember when I once had to override phase with my own macro just to make orgs work correctly. IIRC if you used phase, and then did something like 'org *+1', '*' would expand to the non-phased address, breaking everything. In my case, S2's '_move' psudoinstructions would insert huge amounts of padding into the ROM. I think this was back when I was making a 32X test ROM for my Clone Driver. Bloody annoying.
    Last edited: Apr 16, 2018
    FireRat, ProjectFM and Natsumi like this.
  5. Nat The Porcupine

    Nat The Porcupine Newcomer Member

    Jun 23, 2017
    York, Pennsylvania (USA)
    Man, I thought I've had a rough experience with AS, but these are some horror stories!

    It's such a shame that the Sonic 2 and Sonic 3 & Knuckles disassemblies use AS as their assembler of choice, and given the amount of work and tedium that would go into translating them to ASM68K, it looks like it'll stay that way. Is there even anything good you can say about AS? Sure, it does have support for multiple processors, but the most support you would ever need as a megadrive developer is 68k, Z80, and SuperH; the rest is just bloat. In fact, the assembler is so bloated that it can be dreadfully slow, which is especially apparent if you're migrating from ASM68K. One thing, nay... the ONLY thing that I can say I legitimately like about AS is nameless temporary labels. Even so, I would take needing to give my labels proper names over having to deal AS's bullshit any day.
    Last edited: Apr 16, 2018
    FireRat and ProjectFM like this.
  6. Natsumi

    Natsumi Markey's Member

    Oct 7, 2011
    Otter's lap
    Oh god yes, those random build fuckups thay only go away with inserting more code or removing some old one! I just hate that to death, its been haunting a S3K hack I've been working on... We found a pretty easy way to fix it; If you ever get them, you can have a rept of say, $40 longwords of whatever garbage. You still have to switch between $40 and 0, but its a quick way to get rid of it. Still doesn't mean ASS is the shittiest most broken program I've dealt with.

    Oh and, ASM68K's obj is the same as phase pretty much