我可以使用二进制在汇编中编写整数常量吗? [英] Can i use binary to write integer constants in assembly?
问题描述
我有一个作业,要求定义4个整数,每个整数的字节长度不同(1、2、4、8)
i have an assignment that asks to define 4 integers, each of a different byte length (1, 2, 4, 8)
此代码行得通吗?
segment .data
one db 1
two dw 01
four dd 1011
eight dq 01101110
global _start
_start:
mov rax, [one] ;
mov rbx, [two] ;
我还好奇我是否可以安全地将这些值存储到寄存器中,以备将来使用.我应该对较短的值使用符号扩展名,但可以使用一些方向
im also curious if i can safely store these values into registers to be used for addition in the future. I'm supposed to use sign extension for the shorter values, but could use some direction
推荐答案
您正在用十进制编写常量.如果希望将数字解释为以2为底的数字,则需要将其告知汇编程序.这样做并不是仅仅因为它们碰巧都是0或1.
You're writing constants in decimal. If you want the digits to be interpreted as base-2, you need to tell the assembler about it. It's not going to do that just because they happen to all be 0 or 1.
3.4.1数字常量(第一个Google搜索为:nasm二进制常量):
3.4.1 Numeric Constants in the NASM online manual (first google hit for: nasm binary constant):
一些示例(都产生完全相同的代码):
Some examples (all producing exactly the same code):
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
很明显,您可以在任何地方的常量上使用这些前缀或后缀,而不仅仅是立即数.
Obviously you can use these prefixes or suffixes on constants anywhere, not just immediate operands.
是的,您可以使用二进制文件.请注意,您问题中的代码对存储在 one
中的值使用了一个位常量,而不是一个一字节的常量. one = 1
和 two = 2
,但是 four = 2 ^ 3 + 0 + 2 ^ 1 +1 = 11(十进制)
.
So yes, you can use binary. Note that the code in your question used a one-bit constant, not a one-byte constant, for the value stored in one
. one = 1
, and two = 2
, but four = 2^3 + 0 + 2^1 + 1 = 11(decimal)
.
八个
的定义与此类似.应该是 eight = 1000b
.
eight
is similarly strangely defined. It should be eight = 1000b
.
所有2的幂的整数在其二进制表示形式中都只设置了一位,就像所有10的幂的数字在其十进制表示形式中只有一个 1
一样.
All power-of-two integers only have a single bit set in their binary representation, just like all power-of-10 numbers have a single 1
in their decimal representation.
也许这些名字只是宽度,而不是值?
Maybe those names were just the widths, not the values?
mov rax,[one]
是8字节负载,跨越 db
, dw
和 dd
,以及 dq
的第一个字节.
mov rax, [one]
is an 8-byte load, spanning the db
, dw
, and dd
, and the first byte of the dq
.
mov
指令的唯一形式sign-extension是 mov r64,imm32
,它对立即数而不是内存源进行符号扩展. mov
的两个操作数的大小始终相同(imm32情况除外);不幸的是,它甚至没有像 add r/m64,imm8
这样的符号扩展的imm8形式.
The only form of the mov
instruction that does any sign-extension is mov r64, imm32
, and that sign-extends the immediate, not a memory source. Both operands for mov
are always the same size (except for the imm32 case); it unfortunately doesn't even have a sign-extended imm8 form like add r/m64, imm8
does.
如果要使用符号扩展名从内存中加载,请查找 movsx
insn ref手册中.(从 x86 信息Wiki的链接). movsx rax,字节[mem]
.在您的情况下,零扩展将产生相同的结果: movzx eax,字节[one]
可以零扩展到RAX.(通常更喜欢零扩展;在某些CPU上,它的效率会更高一些.)
If you want to load from memory with sign-extension, look up movsx
in the insn ref manual. (linked from the x86 info wiki.) e.g. movsx rax, byte [mem]
. In your case, zero-extending would give the same result: movzx eax, byte [one]
to zero-extend into RAX. (Generally prefer zero-extension; on some CPUs it's slightly more efficient.)
(此外,您通常需要默认rel
,因此 [one]
是相对于RIP的寻址模式.)
(Also, you normally want default rel
so [one]
is a RIP-relative addressing mode.)
这篇关于我可以使用二进制在汇编中编写整数常量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!