On Fri, 26 Jul 1996, Eric Smith wrote: > I added to my own assembler an "assume" directive (inspired by the disgusting > bsf status,rp0 > assume 1 > ; muck about in bank 1, assembler will generate errors for any attempt to > ; directly access registers in bank 0 > Actually I usually use a macro that does both the rp0 twiddling and the This is very like the macro hack I've found so useful, but because it's built into the assembler you don't need to use reg(someRegisterName) in instructions. (After I had this working someone, perhaps Andrew, mentioned a completely different approach that would fix this, but code assembles so slowly with this relatively low-overhead hack that I'm not real excited about making every instruction a macro). > assume. I didn't make the assembler automatically track the bsf and bcf > instructions because that leads to sloppy thinking and problems like: > > subr1: bsf status,rp0 > ... > call subr2 > ... Well, there's no problem if the assembler recognizes that a subroutine call can change the page select. This was where I got in trouble before, since a really helpful assembler could determine both the entry and exit conditions for a subroutine and use them to good effect, but this can easily turn into a far more complex process. If I were to set out to implement something like this starting tomorrow, I think I would make the pre and post conditions something you'd have to declare before either calling or defining the body of a subroutine - this eliminates a lot of need for the compiler to deduce this stuff. But then I thought that protoypes were one of the best things added by Standard C, and mandantory use and checking of them one of the biggest improvements in C++. :-) > subr2: movwf porta > ... > return > > If the assembler tried to do simple automatic bank tracking based on the bcf > and bsf instructions, it would incorrectly think that subr2 was executed in > bank 0. Also, moves to the status register would confuse it. And that could be if_else2: rather than a subroutine entry and it woud ahve much the same problem. That's the other reason I stopped working on the macro hack well short of much more than what it sounds like you've implemented. I did think the subroutine case was important enough that I have a macro used to make the call and then fiddle the page state variable and one used to define subroutine entries. They're crude in their current form and always make worsy case assumptions, leaving the page state set to "unknown". So far the overhead for unnecessary page bit twiddling hasn't been a problem. > I also had to add a directive that tells the assembler which locations are > identical in both banks. For example, PCL, RTCC, and in some PICs the RAM. That's one advantage - probably the only one! - of the reg() macro. For normal RAM registers I write, as I have become accustomed to bsf reg(someFlagSet), SFS_ERROR_BIT but for the special registers I can just omit the macro btfsc STATUS, CARRY It's not perfect, but it works well enough. And it was real easy to implement. :-)