On Sep 17,
4:26, Derek Peschel wrote:
Pete, I replied to your other post in this thread. I'm just trying to
understand what "the right thing to do" is here.
Well, I'd say the
"right thing to do" is to use absolute addressing modes.
What modes 6/7 do is generate references which are relative to the
instruction address. They're meant for things that will move if the code
is moved (eg the target of a JSR). However, the address of a device
register doesn't move, so although it's possible to refer to using modes
6/7, it breaks the position-independance of the code. If you move the
code, you need to recalculate the address offset.
Once assembled, the first part of Pat's code, despite using mode 6, is not
PIC:
4 177564 XSR=177564
5 177566 XBUF=177566
6
7 001000 012767 000110 177566' MOV #110,XBUF
8 001006 105767 177564' L1: TSTB XSR
9 001012 100375 BPL L1
10 001014 012767 000064 177566' MOV #64,XBUF
11 001022 105767 177564' L2: TSTB XSR
12 001026 100375 BPL L2
13 001030 012767 000130 177566' MOV #130,XBUF
The actual values in the finally-assembled code would be (if I've done my
arithmetic correctly):
7 001000 012767 000110 176552 MOV #110,XBUF
8 001006 105767 176550 L1: TSTB XSR
9 001012 100375 BPL L1
10 001014 012767 000064 176536 MOV #64,XBUF
11 001022 105767 176534 L2: TSTB XSR
12 001026 100375 BPL L2
13 001030 012767 000130 17652 2 MOV #130,XBUF
Note that the pointers to XSR and XBUF change according to their position
in the code, because they're PC-relative (even if my PC-relative arithmetic
is wrong, the differences are correct).
Now if he'd written it using absolute addresses:
7 001000 012737 000110 177566 MOV #110,@#XBUF
8 001006 105737 177564 L1: TSTB @#XSR
9 001012 100375 BPL L1
10 001014 012737 000064 177566 MOV #64,@#XBUF
11 001022 105737 177564 L2: TSTB @#XSR
12 001026 100335 BPL L2
13 001030 012737 000130 177566 MOV #130,@#XBUF
... they don't change. Moreover, since there are no JMPs or JSRs, only
(relative) BRanches, this is PIC.
Now if he wanted to write it using a subroutine, and he used the simple
method:
7 001000 012701 000110 MOV #'H', R1
8 001006 004537 JSR R5, @#PUT
9 001012 012701 000064 MOV #'4', R1
10 001014 004537 JSR R5, @#PUT
11 001022 012701 000130 MOV #'X', R1
12 001026 004537 JSR R5, @#PUT
:
:
35 001100 105767 177564 PUT: TSTB @#XSR
36 001104 100375 BPL PUT
37 001106 010137 177566 MOV R1, @#XBUF
38 001112 000205 RTS R5
That's hand-assembled, in a hurry, so don't rely on the opcodes being
correct! but the point is that the subroutine is referred to by its
absolute address, so the first part of the code can be moved but not the
subroutine (because its address is fixed). However, if it were written
using relative addressing, ie
8 001006 004567 JSR R5, PUT
:
35 001100 105767 177564 PUT: TSTB @#XSR
then the whole thing can be placed anywhere in memory without alteration
(so
long as the subroutine stays in the same position relative to the rest).
Of
course, the subroutine still uses absoute addresses for the registers.
Does that make it clear what the point of the two types of addressing is?
My example is a bit contrived; that's not really how I'd do it. Instead,
I'd write a subroutine that wrote out a whole string, the string being
stored immediately after the JSR, and returning to the word after the
string. But that's another story.
--
Pete Peter Turnbull
Network Manager
University of York
Jerome Fine replies:
All of which implies, in my opinion, that programming has elements
of an artistic endeavor. In addition, there is no absolute correct
way, only a preferred manner. Depending on the goals and the
environment in which the program runs and is developed, that
preferred manner can change.
And while so-called efficient assembler language programming is
often measured by the total number of instructions combined with
the speed of execution, code that is easy to understand is also, in
my opinion, even more important. In regard to this latter aspect,
in most situations, my personal experience has been that code
which is easy to understand depends more on the visual aspects
plus the comments, but two additional criteria are even more
important for large programs:
(a) The realization that almost all programs have bugs that will need
to be eliminated long after the original designer/implementor has
departed from the project. Enhancements will be even more
frequent. After a number of years, even the original group who
develops a large project will forget some of the details. Adequate
documentation at a very high level is critical.
(b) Modular design of a large program is usually essential to
ensure adequate control, but not always. There are a few
situations when one huge program is still more manageable.
Sincerely yours,
Jerome Fine
--
If you attempted to send a reply and the original e-mail
address has been discontinued due a high volume of junk
e-mail, then the semi-permanent e-mail address can be
obtained by replacing the four characters preceding the
'at' with the four digits of the current year.