Add two 32-bit numbers using 8-bit registers

匆匆过客 提交于 2021-02-10 14:39:48

问题


The goal here is two add two 32-bit numbers stored in little-endian notation. The numbers are stored in the following memory cells:

  • first number: 0x3000-0x3003
  • seconds number: 0x4000-0x4003
  • the result should go into: 0x5000-0x5003

The following is my implementation, that is not very efficient in terms of DRY principle:

ARG1 EQU 3000H
ARG2 EQU 4000H
RESULT EQU 5000H

ORG 0000H
    
MOV DPTR, #ARG1 + 0
MOV A, #12H
MOVX @DPTR, A
MOV DPTR, #ARG1 + 1
MOV A, #34H
MOVX @DPTR, A
MOV DPTR, #ARG1 + 2
MOV A, #00H
MOVX @DPTR, A
MOV DPTR, #ARG1 + 3
MOV A, #00H
MOVX @DPTR, A

MOV DPTR, #ARG2 + 0
MOV A, #00H
MOVX @DPTR, A
MOV DPTR, #ARG2 + 1
MOV A, #00H
MOVX @DPTR, A
MOV DPTR, #ARG2 + 2
MOV A, #56H
MOVX @DPTR, A
MOV DPTR, #ARG2 + 3
MOV A, #78H
MOVX @DPTR, A

MOV DPTR, #ARG1 + 0
MOVX A, @DPTR
MOV R0, A
MOV DPTR, #ARG2 + 0
MOVX A, @DPTR
ADDC A, R0
MOV DPTR, #RESULT + 0
MOVX @DPTR, A

MOV DPTR, #ARG1 + 1
MOVX A, @DPTR
MOV R0, A
MOV DPTR, #ARG2 + 1
MOVX A, @DPTR
ADDC A, R0
MOV DPTR, #RESULT + 1
MOVX @DPTR, A

MOV DPTR, #ARG1 + 2
MOVX A, @DPTR
MOV R0, A
MOV DPTR, #ARG2 + 2
MOVX A, @DPTR
ADDC A, R0
MOV DPTR, #RESULT + 2
MOVX @DPTR, A

MOV DPTR, #ARG1 + 3
MOVX A, @DPTR
MOV R0, A
MOV DPTR, #ARG2 + 3
MOVX A, @DPTR
ADDC A, R0
MOV DPTR, #RESULT + 3
MOVX @DPTR, A

JNC EXIT
INC A
MOVX @DPTR, A

EXIT:
  NOP
  SJMP $

END

Question: I was wondering if there is a way to implement this using loop and reduce the repetitive instructions?

For instance this example is using register banks when using 8-bit memory addresses in direct addressing mode:

ORG 0H

MOV 30H, #12H
MOV 31H, #34H
MOV 32H, #00H
MOV 33H, #00H

MOV 40H, #00H
MOV 41H, #00H
MOV 42H, #56H
MOV 43H, #78H

MOV R0, #30H    ;pointer of bank 0
MOV R1, #50H    ;result storage bank 0
MOV R2, #4      ;counter
SETB RS0
MOV R1, #40H    ;pointer bank 1
CLR RS0
CLR C 

LOOP:
  MOV A, @R0
  SETB RS0
  ADDC A, @R1
  INC R1
  CLR RS0
  MOV @R1, A
  INC R0
  INC R1
  DJNZ R2, LOOP

  JNC EXIT
  INC @R1

EXIT:
  NOP
  SJMP $

END

(I'm using µVision IDE)


回答1:


Knowing that the low bytes of the external memory addresses are identical (00h), can simplify the code. It means we can keep the low byte of the data pointer DPTR (special function register DPL at address 82h) fixed throughout an iteration of the loop.
To switch between the 3 external dwords we need just change the high byte of the DPTR (special function register DPH at address 83h).

To move on to the next higher byte in all the dwords involved, I have used the INC 82h instruction at the bottom of the loop. It is important to use INC (and not ADD) because INC does not change the carry flag C that we want propagating through the loop.

  MOV  82h, #00h   ; DPL = 00h
  MOV  R1, #4      ; Each dword has 4 bytes
  CLR  C           ; Clear carry so 1st ADDC works fine
LOOP:
  MOV  83h, #30h   ; DPH = 30h --> DPTR == [3000h,3003h]
  MOVX A, @DPTR    ; Load byte from 1st dword
  MOV  R0, A       ; Free the accumulator (MOVX needs A)
  MOV  83h, #40h   ; DPH = 40h --> DPTR == [4000h,4003h]
  MOVX A, @DPTR    ; Load byte from 2nd dword
  ADDC A, R0       ; Addition defines carry
  MOV  83h, #50h   ; DPH = 50h --> DPTR == [5000h,5003h]
  MOVX @DPTR, A    ; Store byte in 3rd dword
  INC  82h         ; DPL++
  DJNZ R1, LOOP    ; Decrement counter and loop back if not zero

  ; Process the final carry as needed


来源:https://stackoverflow.com/questions/65480542/add-two-32-bit-numbers-using-8-bit-registers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!