Assembly (What if -- 3) -- C" compatible source file comments

We have demonstrated the use of the HVZ memory operation notation for use as comments to the assembly language operations to explain what is occurring during the code. Another school of thought is to make use of a "high level language" line of code to document each assembly line's operation. You may prefer this comment approach if you are already familiar with programming in "C" or "C++".

In addition, later we will be linking "C" language subroutines with our assembly language files. It is therefore useful to get familiar with this operation by making use of "C" language code as comments.


Using the HVZ memory operation notation as comments

As a reminder, this is file e1v2.s using the HVZ memory operation notation as comments

; Code from  HVZ Computer Organization
; Chapter 2 -- Figure 2.26 -- page 67
; A 68000 routine for C <- [A] + [B]

*******************************************************

C	EQU	0x202200	; Specify location to store the result

	section const		; Start of CONSTANTs section
A	DC.W	639		; Specify and initialize a constant value
B	DC.W	-215		; Specify and initialize a constant value

	section code		; Start of CODE (program) section
	.EXPORT mycode
mycode
	MOVE	A, D0		; D0 <- [A]
	ADD	B, D0		; D0 <- [D0] + [B]
	MOVE	D0, C		; C  <- [D0]
	END		

Using "C" language code lines as comments

One of the advantages of using a high level language such as "C" is that the majority of the time the code developed by a compiler is efficient enough for the task we have in mind. On some occasion, assessing external devices or in tight loops, we may find that coding a subroutine in assembler is the approach to take. Being famliar with the relationship between "C" and assembly code is therefore a useful skill to develop. One approach to developing this skill is to use "C" syntax as the comments for assembly language code. You will often find that one line of "C" code will very effectively comment many lines of assembler in a way that "normal English" would not.

Using "C" language lines as comments for the memory operations performed during each instruction can look a bit strange. The strangeness occurs as we are not using "C" as it is currently used -- a "high level" language. Instead we are using "C" as it was originally designed -- a "portable assembly language" . Portable means the same notation used across many different processors.

File e1v2c.s shows Task 1 expressed with "C" language comments. The next section will explain why the syntax is this way.

; Code from  HVZ Computer Organization
; Chapter 2 -- Figure 2.26 -- page 67
; A 68000 routine for C <- [A] + [B]

; "C" comment version

*******************************************************

C	EQU	0x202200	; Not exactly #define C 0x202200
		; (Actually this statement is more properly expressed as
		; the following "casting" operation as "C" is a specific
		; memory location. Accessing a user defined memory location is
		; not a standard operation in the "C" language
		;  	short int *C;
		;  	#define CADDRESS 0x202200;
		;  	C = (short int *) CADDRESS;


	section const		; Start of const section (linker operation)
A	DC.W	639		  ; short int A = 639
B	DC.W	-215		  ; short int B = -215

	section code		; Start of CODE (program) section (linker operation)
	.EXPORT mycode		; void mycode(void) {
mycode				; 	register short int D0;
	MOVE	A, D0		; 	D0 = A;
	ADD	B, D0		; 	D0 += B;
	MOVE	D0, C		; 	*C = D0;
	RTS			; }
	END			; ("C" source EOF marker)

Explaining memory and processor operations in terms of "C" syntax


Use assembler not "C" when accessing I/O devices

Actually if you are using a "good optimizing" C compiler, you are not finished yet.

Optimizing compilers can speed up code operation by taking into account where in your code you reuse variables. These variables are stored directly in registers for fast quick reuse. This can cause a problem if the pointer C points to a register in an I/O device, then the value can change (from some external device operation) in that device register without being changed from inside the "C" program code. This will confuse the optimizing compiler as it will re-use the old stale (out-of-date) value.

You can force the compiler not to store the "device register value" by using the "C" keyword volatile as in

; volatile short int *C;
; const long int CADDRESS = 0x202200;
; C = (volatile short int *) CADDRESS;

Using the volatile keyword is very confusing, especially if you are not sure of its use and whether the "C" compiler does or does not handle this new keyword volatile correctly.

A more reliable approach is to specifically code all functions that access I/O devices directly in assembler code. Then you will know what should happen. The mistakes become obvious rather than hidden by the compiler.This approach of using assembly language I/O functions is one that SDS recommends in their USER manuals, and is the approach that I will adopt for the "Laboratory Companion".



Last modified: July 01, 1996 09:38 AM by M. Smith.
Copyright -- M. R. Smith