What is the correct gnu assembly syntax for doing the following:
.section .data2
.asciz "******* Output Data ********"
total_sectors_written: .word 0x0
max_buffer_sectors: .word ((0x9fc00 - $data_buffer) / 512) # <=== need help here
.align 512
data_buffer: .asciz "<The actual data will overwrite this>"
Specifically, I'm writing a toy OS. The code above is in 16-bit real mode. I'm setting up a data buffer that will be dumped back to the boot disk. I want to calculate the number of sectors there are between where data_buffer
gets placed in memory, and the upper bound of that data buffer. (Address 0x9fc00 is where the buffer would run into RAM reserved for other purposes.)
I know I could write assembly code to calculate this; but, since it is a constant known at build time, I'm curious if I can get the assembler to calculate it for me.
I'm running into three specific problems:
(1) If I use $data_buffer
I get this error:
os_src/boot.S: Assembler messages:
os_src/boot.S:497: Error: missing ')'
os_src/boot.S:497: Error: can't resolve `L0' {*ABS* section} - `$data_buffer' {*UND* section}
which I find confusing, because I should use $
when I want the memory address of a label, correct?
(2) If I use data_buffer
instead of $data_buffer
, I get this error:
os_src/boot.S: Assembler messages:
os_src/boot.S:497: Error: missing ')'
os_src/boot.S:497: Error: value of 653855 too large for field of 2 bytes at 31
make: *** [obj/boot/dd_test.o] Error 1
which seems to suggest that the assembler is complaining about the size of the intermediate value (which does not need to fit in a 16-bit word).
(3) And, of course, what's up with the missing ')'?
$
. Even so, you are limited in what you can do. Also note using multiple sections and gas in general for 16 bit code is not a good idea. PS: my assembler (v2.22) complains thatinvalid operands (*ABS* and .data2 sections) for '-'
and that at least makes sense. – October$
inappropriate in this case? (I figured out that it was by trial-and-error, but am still confused when to use$
and when not to.) (See also #43593184) – Wilda$
is a signal for an immediate operand in an instruction only, it tells the assembler to emit an immediate and not an effective address. Also it applies to the whole operand, not the symbol, e.g.movl $4+foo, %eax
is legal. – Octobernasm
, but in general you don't want to link the 16 and 32 bit code. Let nasm produce flat binary output and use your build system to construct the image as appropriate. Transitions usually happen through fixed addresses. – October