nasm报错:operator may only be applied to scalar values

  搜到了一篇不错的帖子:

  (回答的那个人实在是太敬业了)


Hey all.

I'm a complete beginner in assembly and have chosen NASM to work my way up with. But I have a problem with the pseudo-instruction set. More precisely, I don't understand how the expressions "$ and $$" are used in correlation with times.

It's no problem for me to understand what "times" does, but I do not understand the expressions used together with times.

Like;

times 512-($-$$) db 0

It is explained what it does (in the tutorial), but not how it is done.

My questions according to this example;
1. Why is there a dash ("-") after 512 and before "(" ?
2. Can someone elaborate what $ means and is used for?
3. Can someone elaborate waht $$ means and is used for?

I read the 2 lines of description about $ and $$ multiple times now, and I still don't understand what they are. Can someone help?


下面是回答:
The mysterious '-' is a minus sign. That takes care of that part. :)

Nasm uses '$' for several purposes, in this case it's "here" - the current assembly location. Actually, the location at the beginning of the line.

'$$' is the beginning of the current section.

You might reasonably think that '$' would be enough, but '$', like any symbol, is a "relocatable value". That is, the linker and loader can alter this value in ways Nasm knows nothing about. In the specific case of "-f bin" output, Nasm acts as its own linker, but that happens in the "output driver", and we need to know this value in the actual "assemble" routine, which runs first. This is what Nasm means when it says "not a scalar value". It's a vector??? No, it's a "relocatable value".

In some cases, a relocatable value is okay...

Code: [Select]
mov eax, $

Nasm doesn't need to know the value at "assemble-time", it codes "mov eax, (this label)", and the linker/loader will fill in the relocated value. But:

Code: [Select]
mov eax, $ << 1

... now we're asking Nasm to do an assemble-time calculation on a value it doesn't know, so it whines.

The difference between two labels (in the same section!) is a "scalar value". The linker/loader can change the two values, but the distance between them remains the same. Therefore, we can do a calculation on it - and it's an acceptable argument to "times".

Code: [Select]
org 0 ; the default, if no origin specified
section .text ; the default, if no section specified

nop
nop
nop ; three bytes of "code"

times 512 - ($ - $$) db 0

In this case, '$' is 3 and '$$' is 0, so we're emitting 509 zeros to bring the total file size to 512 bytes. In this case, just '$' would have worked, if Nasm would accept it, which it won't.

Code: [Select]
org 7C00h
section .text

nop
nop
nop ; three bytes of "code"

times 512 - ($ - $$) db 0

Now, '$' is 7C03h and '$$' is 7C00h. We're still adding 509 zeros to pad to 512 bytes, but in this case '$' by itself would *not* do what you want!

The expression "512 - ($ - $$)" can be written without the parentheses as "512 + $$ - $", but this is even less clear (IMHO). In a bootsector, 510 is more common than 512, since we want the two byte "boot signature" after it, and the entire bootsector needs to be 512 bytes, but that doesn't alter '$' and '$$'...

Does that make you less confused, or more? :)

Best,
Frank


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值