NASM Forum > Programming with NASM
Nested label enhancement
(1/1)
Crysein:
Hello,
Local label is a very nice feature that enhance the possibility of name mangling, but it doesn't support multiple root label, here's what I would like.
--- Code: ---ACPITable:
;{
.RSDP:
;{
.Signature: db "RSD PTR "
.Checksum: db 0
.OEMID: times 6 db 0
.Revision: db 0
.RsdtAddress: dd 0
.Length: dd 0
.XsdtAddress: dq 0
.ExtendedChecksum: db 0
.Reserved: times 3 db 0
.Size: dd $ - RSDP
;}
.EndRSDP:
.XSDT:
;{
.Signature: db "XSDT"
.Length: dd 0
.Revision: db 0
.Checksum: db 0
.OEMID: times 6 db 0
.OEMTableID: times 8 db 0
.OEMRevision: dd 0
.CreatorID: dd 0
.CreatorRevision: dd 0
.Entry: times 19 dq 0
.Size: dd $ - XSDT
;}
.EndXSDT:
;}
--- End code ---
But I cannot since the only parent label possible of local label is ACPITable.
debs3759:
If I properly understand what you want to do, you may find the STRUC and ISTRUC macros (section 4.11.10 and 4.11.11 in the nasm docs) useful.
Crysein:
--- Quote from: debs3759 on August 18, 2021, 12:08:22 AM ---If I properly understand what you want to do, you may find the STRUC and ISTRUC macros (section 4.11.10 and 4.11.11 in the nasm docs) useful.
--- End quote ---
It doesn't work
--- Code: ---ACPITable:
;{
struc .RSDP
;{
.Signature: db "RSD PTR "
.Checksum: db 0
.OEMID: times 6 db 0
.Revision: db 0
.RsdtAddress: dd 0
.Length: dd 0
.XsdtAddress: dq 0
.ExtendedChecksum: db 0
.Reserved: times 3 db 0
.Size: dd $ - .RSDP
;}
endstruc
struc .XSDT
;{
.Signature: db "XSDT"
.Length: dd 0
.Revision: db 0
.Checksum: db 0
.OEMID: times 6 db 0
.OEMTableID: times 8 db 0
.OEMRevision: dd 0
.CreatorID: dd 0
.CreatorRevision: dd 0
.Entry: times 19 dq 0
.Size: dd $ - .XSDT
;}
endstruc
;}
EndACPITable:
--- End code ---
gives NASM output:
--- Quote ---Source\Kernel.asm:50: error: label `ACPITable.Length' inconsistently redefined
Source\Kernel.asm:38: info: label `ACPITable.Length' originally defined here
Source\Kernel.asm:51: error: label `ACPITable.Revision' inconsistently redefined
Source\Kernel.asm:35: info: label `ACPITable.Revision' originally defined here
Source\Kernel.asm:52: error: label `ACPITable.Checksum' inconsistently redefined
Source\Kernel.asm:33: info: label `ACPITable.Checksum' originally defined here
Source\Kernel.asm:54: error: label `ACPITable.OEMID' inconsistently redefined
Source\Kernel.asm:34: info: label `ACPITable.OEMID' originally defined here
Source\Kernel.asm:62: error: label `ACPITable.Size' inconsistently redefined
Source\Kernel.asm:43: info: label `ACPITable.Size' originally defined here
--- End quote ---
fredericopissarra:
--- Quote from: Crysein on August 18, 2021, 11:16:14 AM ---It doesn't work
--- End quote ---
Because it is wrong. Here:
--- Code: --- bits 32
struc rsdp
.signature: resb 8
.checksum: resb 1
.oemid: resb 6
.revision: resb 1
.rsdtaddr: resd 1
.length: resd 1
.xsdtaddr: resd 1
.extcksum: resb 1
.reserved: resb 3
.size: resd 1
endstruc
struc xsdt
.signature: resb 8
.length: resd 1
.revision: resb 1
.checksum: resb 1
.oemid: resb 6
.oemtableid: resb 8
.oemrevision: resd 1
.creatorid: resd 1
.creatorrevision: resd 1
.entry: resq 19
.size: resd 1
endstruc
section .data
acpitable:
.rsdp:
istruc rsdp
at rsdp.signature, db "RSD PTR "
at rsdp.xsdtaddr, dd acpitable.xsdt
at rsdp.size, dd rsdp.size ; or rsdp_size - 4
iend
.xsdt:
istruc xsdt
at xsdt.signature, db "XSDT"
at xsdt.size, dd xsdt.size ; or xsdt_size - 4
iend
section .text
global get_xsdt_creatorid
get_xsdt_creatorid:
call get_rsdp_xsdtaddr
mov eax,[eax + xsdt.creatorid]
ret
global get_rsdp_xsdtaddr
get_rsdp_xsdtaddr:
mov eax,[acpitable.rsdp + rsdp.xsdtaddr]
ret
--- End code ---
Crysein:
--- Quote from: fredericopissarra on August 18, 2021, 09:38:11 PM ---
--- Quote from: Crysein on August 18, 2021, 11:16:14 AM ---It doesn't work
--- End quote ---
Because it is wrong. Here:
--- Code: --- bits 32
struc rsdp
.signature: resb 8
.checksum: resb 1
.oemid: resb 6
.revision: resb 1
.rsdtaddr: resd 1
.length: resd 1
.xsdtaddr: resd 1
.extcksum: resb 1
.reserved: resb 3
.size: resd 1
endstruc
struc xsdt
.signature: resb 8
.length: resd 1
.revision: resb 1
.checksum: resb 1
.oemid: resb 6
.oemtableid: resb 8
.oemrevision: resd 1
.creatorid: resd 1
.creatorrevision: resd 1
.entry: resq 19
.size: resd 1
endstruc
section .data
acpitable:
.rsdp:
istruc rsdp
at rsdp.signature, db "RSD PTR "
at rsdp.xsdtaddr, dd acpitable.xsdt
at rsdp.size, dd rsdp.size ; or rsdp_size - 4
iend
.xsdt:
istruc xsdt
at xsdt.signature, db "XSDT"
at xsdt.size, dd xsdt.size ; or xsdt_size - 4
iend
section .text
global get_xsdt_creatorid
get_xsdt_creatorid:
call get_rsdp_xsdtaddr
mov eax,[eax + xsdt.creatorid]
ret
global get_rsdp_xsdtaddr
get_rsdp_xsdtaddr:
mov eax,[acpitable.rsdp + rsdp.xsdtaddr]
ret
--- End code ---
--- End quote ---
omg, way too much complicated for label management.
This code looks like C trying to be OOP
I want something that keep the local label mechanism but enhanced, like this:
--- Code: ---ACPITable:
;{
.RSDP:
;{
Signature: db "RSD PTR "
Checksum: db 0
OEMID: times 6 db 0
Revision: db 0
RsdtAddress: dd 0
Length: dd 0
XsdtAddress: dq 0
ExtendedChecksum: db 0
Reserved: times 3 db 0
Size: dd $ - RSDP
List:
;{
.VarA: db 0
.Case:
;{
VarA: db 0
;}
.EndCase:
;}
EndList:
;}
.EndRSDP:
.XSDT:
;{
Signature: db "XSDT"
Length: dd 0
Revision: db 0
Checksum: db 0
OEMID: times 6 db 0
OEMTableID: times 8 db 0
OEMRevision: dd 0
CreatorID: dd 0
CreatorRevision: dd 0
Entry: times 19 dq 0
Size: dd $ - XSDT
List:
;{
.VarA: db 0
.Case:
;{
VarA: db 0
;}
.EndCase:
;}
EndList:
;}
.EndXSDT:
;}
EndACPITable:
--- End code ---
Ok I explain how this code can be parsed.
Root Label come without dot '.'
Local Label come with a dot '.'
First the assembler detect a root label (ACPITable:) and it ends its scope when seeing another root label (EndACPITable:) and not between root label (Signature: ect) since local label do have scope capability.
So the assembler start the name decoration with "ACPITable."
Then the assembler hit a local label (.RSDP:) add it to the name decoration and open a new scope that await to be closed when hitting another local label.
Inside this local scope(.RSDP:) assembler can add all the labels between and they have to be root label in order to not break the current label scoping.
But seeing root label (List:) inside the current local label scope (.RSDP:) activate another nested scope (3 scope layers at this stage) and ends its scope level when seeing another root label (EndList:)
Thus when arrived at the root label (List:) the assembler add all local label inside the root label (List:) until he found another root label (EndList:) but remember that the assembler open scope each time it see a root or a local label.
Thus the local label (.Case:) open a new inner scope that will add the root label (VarA:) and end its scope to (.EndCase:).
Hope I was clear enough.
I can make a working demo in order to implement it to the next NASM update.
Navigation
[0] Message Index
Go to full version