问题标签 [immediate-operand]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
240 浏览

assembly - RISC-V 立即编码符号究竟是如何工作的?

我以为我已经理解了这一点,但我想我自己很困惑。

RISC-V RV32G 编码

我的印象是 [11:0] 是编码中立即位的顺序。例如,addi x1, x2, 12立即数为 000000001100;addi立即数将从指令编码中的第 20 位开始。

我很困惑这个逻辑如何应用于 U 型编码 [31:12] 中使用的相同符号。我知道 U 型立即数是 20 位,但我现在不确定如何解释这个符号。

0 投票
0 回答
64 浏览

cpu - CPU 需要多少内存引用来执行立即地址指令,为什么?

在立即寻址模式下,我知道在指令本身中我们有操作数的值,而不是操作数的地址。那么,CPU 是否需要任何内存引用,因为操作数的有效地址是指令本身的地址。

任何见解都会非常有帮助。

0 投票
1 回答
289 浏览

assembly - 使用 Arm 内联 GCC 程序集立即加载 16 位(或更大)

注意:为了简洁起见,这里的例子被简化了,所以它们不能证明我的意图。如果我只是像示例中那样写入内存位置,那么C 将是最好的方法。但是,我正在做的事情在这个例子中我不能使用 C,即使一般来说最好留在 C 中。

我正在尝试使用值加载寄存器,但我坚持使用 8 位立即数。

我的代码:

https://godbolt.org/z/8EE45Gerd

当我编写 C 代码(请参阅a()参考资料)时,它会在 Godbolt 中组装成:

我认为它使用MOVas 伪指令。当我想在汇编中做同样的事情时,我可以将值放入某个内存位置并使用LDR. 我认为这就是我使用 -march=ARMv7E-M (MOV替换为LDR)时 C 代码的组装方式,但是在许多情况下,这对我来说并不实用,因为我会做其他事情。

在 0x21014 地址的情况下,前 2 位为零,因此当我正确移位它时,我可以将这个 18 位数字视为 16 位,这就是我在 中所做的b(),但我仍然必须通过它8 位立即数。但是,在 Keil 文档中,我注意到提到了 16 位立即数:

https://www.keil.com/support/man/docs/armasm/armasm_dom1359731146992.htm

https://www.keil.com/support/man/docs/armasm/armasm_dom1361289878994.htm

在 ARMv6T2 及更高版本中,ARM 和 Thumb 指令集都包括:

最低有效一半的内容。

我认为我的 CortexM4 应该是 ARMv7E-M 并且应该满足这个“ARMv6T2 及更高版本”的要求,并且应该能够使用 16 位立即数。

但是,从 GCC 内联汇编文档中,我没有看到这样的提及:

https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html

当我启用 ARMv7E-M 架构并取消注释c()我使用常规“I”立即的位置时,我得到一个编译错误:

所以我想知道有没有办法在 GCC 内联汇编中使用 16 位立即数,或者我是否遗漏了一些东西(这会使我的问题无关紧要)?

附带问题,是否可以在 Godbolt 中禁用这些伪指令?我已经看到它们也与 RISC-V 程序集一起使用,但我更愿意查看反汇编的真实字节码,以了解这些伪/宏程序集指令产生的确切指令。

0 投票
1 回答
59 浏览

c - C/SIMD - 创建一个“立即数组”;返回立即值的数组?

我的意思是使用类似于上面的代码来左打包一个浮点数组,将比较传递给另一个,但它返回错误'最后一个参数必须是 8 位立即数。'我怎样才能做到这一点?

0 投票
0 回答
104 浏览

assembly - 检测立即 32 位操作数 (imm32) 的潜在 MASM 64 位符号扩展错误

我正在尝试编写一个工具来扫描 64 位汇编代码以查找可能的符号扩展错误。
例如,假设一个 32 位常量 (imm32) 定义为

接下来,调用任何返回 SOCKET_ERROR(32 位整数)的 API,并将结果存储在 64 位变量retval中。但是,将retval与 SOCKET_ERROR_INT 进行比较会生成

请注意 SOCKET_ERROR_INT (imm32) 符号扩展为 64 位!(见下表:cmp m64, imm32)但是,qword ptr [rbp-8]0FFFFFFFFh ( retval ),所以比较阴险地失败了!

笔记

立即操作数 (imm32) 是常量值或常量表达式的结果。汇编器在汇编时将立即值编码到指令中。

在某些情况下,MASM 表达式计算器会自动对数字进行符号扩展。符号扩展只能影响从0x800000000xFFFFFFFF的数字。也就是说,符号扩展只影响可以写入 32 位且高位等于 1 的数字。

例如,当调试器将其视为 64 位数字时,数字 0x12345678 始终保持为 0x0000000012345678。另一方面,当 0x890ABCDE 被视为 64 位值时,它可能会保持 0x00000000890ABCDE 或 MASM 表达式评估器可能会将其符号扩展为 0xFFFFFFFF890ABCDE。

这是符号扩展的指令的不完整列表:

offset64.asm

要构建示例,请创建一个makeit64.bat,如下所示:

运行批处理文件会创建此输出。(没有警告或错误)

沉默的 MASM

没有警告、错误和跳转等于 FALSE。例如,

生成

问题:是否有完整的易于签名扩展的指令列表?

0 投票
1 回答
58 浏览

assembly - 在 ARM 汇编中编译 MOV 指令时出错

我正在使用 RVDS6_13 编译器,我的处理器是 Cortex X1 (HERA)。对于需要进行一些汇编语言编程的测试,我在编译时遇到以下错误:

错误:A1616E:当前指令集不支持指令、偏移量、立即数或寄存器组合 9 00000000 MOV x28,0xD02E7F30

基本上我需要加载 0xB41138A4 到地址位置 0xD02E7F30,下面是我的代码:

0 投票
2 回答
59 浏览

assembly - 将单词与即时价值进行比较?

我正在努力掌握如何在 MIPS 中操作/比较存储在寄存器(字/半字/中间值)中的数据。如果它们各自代表不同的字节数有关系吗?例如,通过li加载一个立即数比如5,然后加载一个比如5的单词,最后用bne进行比较是否有效?

0 投票
2 回答
171 浏览

assembly - 为什么 IMUL 的 32 位立即数会在 NASM 中给出警告而在 GCC 中给出错误?

我目前正在调查该imul指令的一些奇怪行为,因为英特尔官方手册似乎与现实略有不同。

我注意到的第一件事是英特尔手册不认为这个例子是正确的指令:

然而 GCC/GAS (with .intel_syntax noprefix) 和 NASM 都毫无问题地接受这个指令。使用objdump -d向我展示了这一点:

这意味着它被翻译成实际上记录在手册中的不同指令。

我已经觉得这很奇怪,并且想知道为什么它会存在。我唯一能找到这个文档的地方是在NASM 指令集中,而且奇怪的是,在imul英特尔手册中的指令描述中。后者写道:

  • 双操作数形式— 使用这种形式,目标操作数(第一个操作数)乘以源操作数(第二个操作数)。目标操作数是通用寄存器,源操作数是立即数、通用寄存器或内存位置。中间产品(输入操作数大小的两倍)被截断并存储在目标操作数位置。

这与同一条指令的操作码表不一致。

NASM指令集也提到imul reg64, sbytedwordimul reg64, imm指令,我都不明白它们的意思。imm这意味着也可以使用 64 位立即数,不是吗?sbytedword我不清楚的含义。

现在到 32 位立即数:NASM 指令集提到imul reg64, imm32,而英特尔手册和 NASM 集都提到imul r64, r/m64, imm32。但是,通常当使用比目标操作数低的位计数的立即数时,英特尔手册在操作码表的描述列中特别提到了符号扩展。在这种情况下,它没有被提及,所以我想知道如果我碰巧使用负的 32 位立即数(换句话说,需要所有 32 位)会发生什么。

这是我测试过的汇编代码:

然后我从 C 中调用了imm_test函数:

如果要对 32 位立即数进行符号扩展,我假设必须打印的值为-2097153,当使用 NASM 进行汇编和 GCC 编译和链接时,这正是打印的内容。
然而 NASM 给了我这个警告:

但是,再次查看反汇编代码,该指令的编码方式与我期望的完全一样:

它是一个 32 位立即符号扩展为 64 位。

当我将汇编代码的语法更改为 GAS 时.intel_syntax noprefix,如下所示:

并尝试使用 GNU 汇编器来组装它,我不只是得到一个警告,我得到一个错误:

将说明更改imul为正确记录的imul rax, rax, 0xFFDFFFFF版本不会改变任何内容。

所以我想知道,为什么文档imul如此不一致,为什么官方支持 32 位立即数(并且也可以正常工作),但它们却给出错误或警告?

0 投票
2 回答
437 浏览

assembly - ARM 程序集中的立即值编码

我现在正在学习汇编语言,我对立即值的编码方式有点困惑。有人可以解释为什么以下值有效:0xff00ff00、0xffffffff、0x007f8000?另外为什么值 0xff0000ff, 0x007f9000 无效?

据我了解,12 位立即数分为 4 个高位旋转和 8 个低位常量。所以我认为我上面列出的所有值都是无效的,因为它需要超过 12 位。

关于这个主题的一些澄清会很有帮助,谢谢!

0 投票
0 回答
27 浏览

assembly - 如何将 64 位二进制文​​字移动到 rax?错误 A2071:初始化程序幅度对于指定大小来说太大

这是我的代码。如果我将二进制值的大小减半为 32 位,它可以工作,但是一旦我尝试 33 位或更高位,我就会得到“错误 A2071:初始化程序幅度对于指定大小而言太大”

这是我的代码:

据我所知,rax 是一个 64 位寄存器,如果我使用这个二进制数的实际数字表示(即 18,446,744,073,709,551,615 = 2^64 - 1),那么它可以工作......但如果我尝试使用 33 或更多实际位值,程序不会汇编

有谁知道如何解决这一问题?

谢谢