mptst_byte.s - translation of 8-bit C aritmetic to assembly

Like mptst_word.s - translation of 16-bit C aritmetic to assembly, this file demonstrates translating a C program into assembly; however, this C project uses 8-bit, rather than 16-bit, values.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
uint8_t u8_i;
uint8_t u8_j;
uint8_t u8_k;

void main(void) {
  u8_i = 100;           // u8_i = 64 (0x64).
  u8_i = u8_i + 1;      // u8_i++, so u8_i = 101 (0x65).
  u8_j = u8_i;          // u8_j is 101 (0x65).
  u8_j = u8_j - 1;      // u8_j--, so u8_j is 100 (0x64).
  u8_k = u8_j + u8_i;   // u8_k = 201 (0xC9).
}

Declare variables

.bss

Reserve one byte (8 bits) for each variable using the .space directive.

;; uint8_t u8_i;
u8_i:   .space 1
;; uint8_t u8_j;
u8_j:   .space 1
;; uint8_t u8_k;
u8_k:   .space 1

This isn’t used, but makes the MPLAB X v. 1.80 watch window display the size of the u8_k variable above correctly.

u8_bug: .space 2
 

Code

.text
.global __reset
__reset:

  ;;  W0     W0
  ;; u8_i = 100;

Input

  mov.b #100, W0

Output. Important note: When MOVing directly from memory to register or vice versa, you must always target WREG (the 8-bit name for W0). You may not use W1, W2, etc.

  mov.b WREG, u8_i
 

This statement requires no register assignments.

  ;; u8_i = u8_i + 1;

Input, process, and output

  inc.b  u8_i

  ;;  W0     W0
  ;; u8_j = u8_i

Input. As discussed above, this 8-bit operation must target WREG.

  mov.b   u8_i, WREG

Output

  mov.b   WREG, u8_j

  ;; u8_j = u8_j - 1;

Input, process, and output

  dec.b   u8_j
 

To make this a bit easier, we’ll re-use W0 to hold both u8_j and u8_k.

  ;;  W0     W0     W1
  ;; u8_k = u8_j + u8_i

Input. First, load u8_i, since it overwrites WREG; then, load u8_j into WREG.

  mov.b u8_i, WREG
  mov.b W0, W1
  mov.b u8_j, WREG

Process

  add.b W0, W1, W0

Output

  mov.b WREG, u8_k

done:
  goto     done    ;Place holder for last line of executed code