你正在用十进制写常量。如果您希望将数字解释为 base-2,则需要告诉汇编程序。不会因为它们恰好都是 0 或 1 就这样做。
3.4.1 Numeric Constants 在 NASM 在线手册中(第一次 google 命中:nasm 二进制常量):
一些例子(都产生完全相同的代码):
mov ax,200 ; decimal
mov ax,0200 ; still decimal
mov ax,0200d ; explicitly decimal
mov ax,0d200 ; also decimal
mov ax,0c8h ; hex
mov ax,$0c8 ; hex again: the 0 is required
mov ax,0xc8 ; hex yet again
mov ax,0hc8 ; still hex
mov ax,310q ; octal
mov ax,310o ; octal again
mov ax,0o310 ; octal yet again
mov ax,0q310 ; octal yet again
mov ax,11001000b ; binary
mov ax,1100_1000b ; same binary constant
mov ax,1100_1000y ; same binary constant once more
mov ax,0b1100_1000 ; same binary constant yet again
mov ax,0y1100_1000 ; same binary constant yet again
显然,您可以在任何地方对常量使用这些前缀或后缀,而不仅仅是直接操作数。
所以是的,您可以使用二进制文件。 请注意,您问题中的代码对存储在one 中的值使用了一个位 常量,而不是一个字节常量。 one = 1,和two = 2,但是four = 2^3 + 0 + 2^1 + 1 = 11(decimal)。
eight 的定义也很奇怪。应该是eight = 1000b。
所有 2 的幂整数在其二进制表示中只设置一个位,就像所有 10 的幂数在其十进制表示中都有一个 1。
也许这些名称只是宽度,而不是值?
mov rax, [one] 是一个 8 字节的加载,跨越 db、dw 和 dd,以及 dq 的第一个字节。
执行任何符号扩展的mov 指令的唯一形式是mov r64, imm32,它对立即数进行符号扩展,而不是对内存源进行符号扩展。 mov 的两个操作数总是相同的大小(除了 imm32 情况);不幸的是,它甚至没有像 add r/m64, imm8 这样的符号扩展 imm8 形式。
如果您想使用符号扩展从内存中加载,请在 insn 参考手册中查找 movsx。 (链接自x86 info wiki。)例如movsx rax, byte [mem]。在您的情况下,零扩展将给出相同的结果:movzx eax, byte [one] 以零扩展为 RAX。 (通常更喜欢零扩展;在某些 CPU 上它的效率略高。)
(另外,您通常需要default rel,所以[one] 是一种相对于RIP 的寻址模式。)