Author Topic: Nested label enhancement  (Read 13567 times)

Offline Crysein

  • Jr. Member
  • *
  • Posts: 5
Nested label enhancement
« on: August 17, 2021, 07:07:29 PM »
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: [Select]
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:
;}

But I cannot since the only parent label possible of local label is ACPITable.
« Last Edit: August 18, 2021, 12:42:39 AM by Crysein »

Offline debs3759

  • Global Moderator
  • Full Member
  • *****
  • Posts: 224
  • Country: gb
    • GPUZoo
Re: Nested local label
« Reply #1 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.
My graphics card database: www.gpuzoo.com

Offline Crysein

  • Jr. Member
  • *
  • Posts: 5
Re: Nested local label
« Reply #2 on: August 18, 2021, 11:16:14 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.

It doesn't work

Code: [Select]
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:

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

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 373
  • Country: br
Re: Nested local label
« Reply #3 on: August 18, 2021, 09:38:11 PM »
It doesn't work
Because it is wrong. Here:
Code: [Select]
  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
« Last Edit: August 20, 2021, 12:19:16 AM by fredericopissarra »

Offline Crysein

  • Jr. Member
  • *
  • Posts: 5
Re: Nested local label
« Reply #4 on: August 20, 2021, 09:25:07 AM »
It doesn't work
Because it is wrong. Here:
Code: [Select]
  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

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: [Select]
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:

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.
« Last Edit: August 20, 2021, 09:49:42 AM by Crysein »