I want to retrieve the high (over 16 bits) part of an address from a label in gpasm code.
Here is my small example test.asm
:
LIST P=PIC18F46Q10
;LIST P=PIC18F47J13
ORG 0
MOVLW TEST_LOCATION & 0xFF
MOVWF 0x500, A
MOVLW (TEST_LOCATION >> 8) & 0xFF
MOVWF 0x501, A
MOVLW (TEST_LOCATION >> 16) & 0xFF
MOVWF 0x502, A
JUST_LOOP
BRA JUST_LOOP
ORG 0x12468
TEST_LOCATION
DB 0xDE, 0xAD, 0xBE, 0xEF
END
The aim of this code is to store the address of TEST_LOCATION
(0x12468
) to some part of the RAM.
Assembler version:
D:\Temp>gpasm -v
gpasm-1.5.2 #1325 (Jan 30 2022)
Assemble command:
gpasm test.asm
Here is a part of resulting test.lst
:
LOC OBJECT CODE LINE SOURCE TEXT
VALUE
00001 LIST P=PIC18F46Q10
00002 ;LIST P=PIC18F47J13
00003
000000 00004 ORG 0
00005
000000 0E68 00006 MOVLW TEST_LOCATION & 0xFF
Message[1302]: RAM Bank undefined in this chunk of code. Ensure that bank bits are correct. Assuming bank 5 from now on.
000002 6E00 00007 MOVWF 0x500, A
000004 0E24 00008 MOVLW (TEST_LOCATION >> 8) & 0xFF
000006 6E01 00009 MOVWF 0x501, A
000008 0E00 00010 MOVLW (TEST_LOCATION >> 16) & 0xFF
00000A 6E02 00011 MOVWF 0x502, A
00012
00000C 00013 JUST_LOOP
00000C D7FF 00014 BRA JUST_LOOP
00015
012468 00016 ORG 0x12468
012468 00017 TEST_LOCATION
Warning[220]: Address exceeds maximum range for this processor. BADROM_START: 0x010000 <= Bad address: 0x012468 <= BADROM_END: 0x30FFFF
Warning[220]: Address exceeds maximum range for this processor. BADROM_START: 0x010000 <= Bad address: 0x012469 <= BADROM_END: 0x30FFFF
Warning[220]: Address exceeds maximum range for this processor. BADROM_START: 0x010000 <= Bad address: 0x01246A <= BADROM_END: 0x30FFFF
Warning[220]: Address exceeds maximum range for this processor. BADROM_START: 0x010000 <= Bad address: 0x01246B <= BADROM_END: 0x30FFFF
012468 ADDE EFBE 00018 DB 0xDE, 0xAD, 0xBE, 0xEF
00019
00020 END
You can see the middle part 0x24
and the lower part 0x68
from the address 0x12468
are correctly embed into the instructions, but the high part 0x01
didn't get embed and zero is stored instead.
I thought that this may be because PIC18F46Q10
, which has 64k-byte program ROM and doesn't have storage at 0x12468
, is selected, so I tried switching to PIC18F47J13
, which has 128k-byte program ROM. However, the high part still got embed as zero.
A part of resulting test.lst
for this case:
LOC OBJECT CODE LINE SOURCE TEXT
VALUE
00001 ;LIST P=PIC18F46Q10
00002 LIST P=PIC18F47J13
00003
000000 00004 ORG 0
00005
000000 0E68 00006 MOVLW TEST_LOCATION & 0xFF
Message[1302]: RAM Bank undefined in this chunk of code. Ensure that bank bits are correct. Assuming bank 5 from now on.
000002 6E00 00007 MOVWF 0x500, A
000004 0E24 00008 MOVLW (TEST_LOCATION >> 8) & 0xFF
000006 6E01 00009 MOVWF 0x501, A
000008 0E00 00010 MOVLW (TEST_LOCATION >> 16) & 0xFF
00000A 6E02 00011 MOVWF 0x502, A
00012
00000C 00013 JUST_LOOP
00000C D7FF 00014 BRA JUST_LOOP
00015
012468 00016 ORG 0x12468
012468 00017 TEST_LOCATION
012468 ADDE EFBE 00018 DB 0xDE, 0xAD, 0xBE, 0xEF
00019
00020 END
What should I do to get the high part of the address 0x01
from the label TEST_LOCATION
with gpasm?
Writing 0x01
directly without using TEST_LOCATION
can be a workaround, but it doesn't look nice.
If you use provided operators, you can obtain the bytes of the address:
MOVLW LOW TEST_LOCATION
MOVWF 0x500, A
MOVLW HIGH TEST_LOCATION
MOVWF 0x501, A
MOVLW UPPER TEST_LOCATION
MOVWF 0x502, A