Author Topic: "shift operator may only be applied to scalar values" when working with labels  (Read 25102 times)

Offline madanra

  • Jr. Member
  • *
  • Posts: 3
Short background: I'm starting writing an operating system. My bootloader just loads a flat binary image to 0x0100:0x0000 and jumps to it.
My problem is, the image may well end up larger than 64KB, so I'd like to set ds to a segment at the beginning of my data section, as the data may not be within 64KB of the start of the image. But this code:
Code: [Select]
mov ax,cs
add ax,((Data-Code)>>4)
mov ds,ax
doesn't work, it give the error "shift operator may only be applied to scalar values". The labels Code and Data are defined immediately after SECTION .text and SECTION .data respectively.
The code
Code: [Select]
mov ax,cs
mov bx,Data
sub bx,Code
shr bx,4
add ax,bx
mov ds,ax
works; so NASM clearly knows the values of Data and Code, but it can't do any calculations with them. Why is this?

Offline Keith Kanios

  • Full Member
  • **
  • Posts: 383
  • Country: us
    • Personal Homepage
THIS and THIS post should give some insight.

Offline madanra

  • Jr. Member
  • *
  • Posts: 3
Ah, thank you - the first link cleared it up! I forget the separation of assembler and linker as I almost always only use flat binary, where the separate stages aren't noticeable, except in cases like this.
I've solved the problem in this case by putting CodeEnd and DataEnd just before the SECTION directives, so I can add up each section separately as I know they'll just be adjacent in the binary.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
I was going to suggest putting a "Code_end:" label at the end of your code. The difference between two labels is a "scalar value", but the two labels have to be in the same section (Nasm complains if you try to subtract labels in two sections, even without the shift operator!)

Okay, so now you can calculate the size of your code, shift it, and add this to cs (which we know is 100h, in this case). Now what? Offsets from your new ds are going to start from zero, but this isn't where Nasm is going to calculate labels in your .data section... unless we give it some help...

Code: [Select]
section .data vstart=0

You may want an "align=16" attribute in there too. Note that "(code_end - code" >> 4" is going to truncate any "odd bytes" - you probably want "(code_end - code + 0Fh) >> 4" to "round up". It may take some fiddling to get this right, but you should be able to do it.

If it wuz easy, everybody'd be doing it! :)

Best,
Frank