Author Topic: Some Suggestions  (Read 18006 times)

Offline cdeee

  • Jr. Member
  • *
  • Posts: 4
Some Suggestions
« on: January 17, 2011, 07:29:50 AM »
Please refer to the following code:

        xor     eax,    eax                   ; some code
        mov    ax,    LABEL1 & 0x00ff   ; error code

If you compile the above code, a error be received.

For labels, NASM support ('+' / '-') operations, but sometimes we wish the ('&' / '|' / '>>' / '<<' / '*' / '/') operations

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Some Suggestions
« Reply #1 on: January 17, 2011, 01:15:52 PM »
Well, you're out of luck. "LABEL1" is a relocatable value, and Nasm won't do those operations on it - requires a "scalar value", defined nowhere, but that's what it means - not relocatable.

The difference between two labels is a "scalar value":

Code: [Select]
mov ax, (LABEL1 - $$) & 0x00FF

May do what you want...


Offline cdeee

  • Jr. Member
  • *
  • Posts: 4
Re: Some Suggestions
« Reply #2 on: January 18, 2011, 06:36:37 AM »
Your idea is so good, Thanks a lot.

Offline Serge

  • Jr. Member
  • *
  • Posts: 26
  • Country: ru
Re: Some Suggestions
« Reply #3 on: April 04, 2011, 08:42:31 AM »
I think that when the assembler output is pure binary, it is better to treat all labels as scalars. Moreover, I'd like to treat this as feature request. First, this will help to optimize code without using obscure label mathematics, the sample is here (first post):
Second, sometimes it is needed to mangle with addresses to solve the task. The obvious examples are: GDT building at assembly time and FAT12 image creation (with files). Both tasks are easily solved with FASM since it has two very valuable features:
- Treating labels as scalars when producing binary output.
- "Load/Store" directives that allow to get and save any calculated data at/from any location.
Please look at the following code:

Code: [Select]
; Segment desciptor definition. Parameters: base, limit, attribs
%macro GDT_entry 3
  .limit: dw (%2)&0FFFFh
  .base_l: dw (%1)&0FFFFh
  .base_m: db ((%1)>>16)&0FFh
  .access: db (%3)&0FFh
  .attribs: db (((%2)>>16)&0Fh) | (((%3)>>4)&0F0h)
  .base_h: db ((%1)>>24)&0FFh

section .data

align 16
gdt: GDT_entry 0, 0, 0 ; Null descriptor
gdt_tss: GDT_entry TSS, TSS.io_map-TSS-1, ATR_TSS ; TSS for task

section .bss

align 4
TSS: ; TSS definition for 386+
  .link: resw 2 ; High word not used
  .esp0: resd 1
  .ss0: resw 2 ; High word not used
; Not interesting part of TSS is omitted
  .io_map_addr: resw 1
  .io_map: resb 8192 ; I/O map for TSS

You know that calculation of GDT entry is very confusing (thanks to Intel!). The arithmetics is done by macro above. The GDT entry for TSS must have the base address pointing to TSS entry. I can't write TSS-$$ to convert relocatable label to scalar in the sample above because the GDT and TSS are in different segments. This calculation is forbidden. One may suggest to place
Code: [Select]
TSSstart equ TSS-$$right after TSS in the same segment and then use TSSstart instead of TSS. But this doesn't work because it gives WRONG result since the start of BSS segment ($$) is not 0, so the calculated address is not physical address of TSS in memory. SEG keyword is forbidden here by NASM since the output is binary.

The loading/storing not only helps to easily create FAT entries for files but allows to, for example, encrypt the parts of code in ASM controlled manner. Please check how this is done in FASM.
BTW, I don't like FASM. The NASM is the best assembler and I want it to be PERFECT :).