我已经阅读了一些教程和示例,但我无法理解MUL指令的工作原理.我已经习惯了ADD,SUB没有问题.显然,该指令将其操作数乘以寄存器中的值.
什么寄存器(eax,ebp,esp等)乘以第一个操作数?存储的结果是什么寄存器,所以我可以将其移动到堆栈中?对不起,我刚学习x86程序集.
当我尝试编译这一行时......
mul 9
Run Code Online (Sandbox Code Playgroud)
我明白了Error: suffix or operands invalid for 'mul'.谁能帮我吗?
global main
main:
push ebp
movl ebp, esp
sub esp, byte +8
mov eax, 7
mul 9
mov [esp], eax
call _putchar
xor eax, eax
leave
ret
Run Code Online (Sandbox Code Playgroud) 最近,我正在研究RV32I基本指令集,我没有发现任何类似于LD r1,imm的指令。因此,我想知道汇编程序员如何将立即数加载到 RV32I 系统中的寄存器中?谢谢。
为此,程序员可以使用 ADDI r1、r0、imm。由于r0是常数0,所以该指令将imm移至寄存器r1。
不知道RV32的设计者是不是这样想的,用ADDI来代替LD r1,imm?
希望任何人都可以对此有所了解。谢谢。
据我所知,SSE/AVX 中没有用于加载立即数的指令。一种解决方法是将值加载到普通寄存器 和movd,但编译器似乎认为这比从内存加载成本更高,即使对于单个标量值也是如此。
这使得每次使用常见常量(例如1、0x80000000、0x7fffffff、0x3f800000、0x3f000000等)进行操作时都需要进行内存访问。好吧,将这些值编码在机器代码中每个将占用 4 个字节,但 32 位绝对或rip相对地址也是如此,而且我相信立即加载比任何类型的内存加载都便宜。
我一直认为有类似movss xmm, imm32或 之类的东西broadcastss xmm, imm32会很好,但不做出这样的指示肯定是有原因的。为什么要这样设计呢?
我正在设计 MIPS 处理器作为我的个人项目,现在我遇到了一个非常困惑的问题。我只是无法总结何时在 MIPS 中使用有符号扩展以及何时使用零扩展。
我搜索了很多资源,主要是说:
1) ADDI, ADDIU 都是使用signed-extend。
2) ANDI、ORI、XORI 都使用零扩展。
但是,在这两条指令中,我开始感到困惑:
SLTIU/SLTI
在 Imagination 的“程序员的 MIPS 架构第 II-A 卷:MIPS 指令集手册”第 368 页中说:

它清楚地提到16位立即数是signed-extend。但我不明白以下语句:
[0, 32767] 或最大 [max_unsigned-32767, max_unsigned] 无符号范围的结尾。
其他一些人说 16 位立即数是零扩展,如下所示:

那么,有人可以解释一下 MIPS 中的有符号指令和无符号指令之间究竟有什么区别吗?
assembly mips system-verilog zero-extension immediate-operand
在MIPS组件中,使用addiuover有addi什么好处?是不是addiu未签名的(会破坏我们的计算?)
addi当使用十六进制立即数时,是否有关于如何在汇编中解释指令(和其他指令)的标准或建议?
例子:
addi $t0, $zero, 0xffff
Run Code Online (Sandbox Code Playgroud)
我期待这意味着相同的addi $t0, $zero, -1地方0xffff是符号扩展到0xffffffff,如由处理器完成的,而是由一个事实,即火星模拟器解释的十六进制数为32张无符号数和尝试的汇编做惊讶addi $t0, $zero, 0x0000ffff的伪指令(如果启用了伪指令)。
需要明确的是,MARS 的汇编器将该addi $t0, $zero, 0xffff伪指令组装为多条机器指令,这些指令在寄存器中创建该常量 (65535 = 0xffff),然后在启用伪指令的情况下添加它。MARS 的模拟器可以正确模拟0x2008ffff( addi $t0, $zero, -1)等指令。
SPIM 汇编器只是因错误而中止。
我想知道的是,汇编程序是否总是以这种方式解释,以及是否有写或解释的地方,因为我找不到任何东西。
MIPS 有一个 Load Immediate ( LI) 伪指令,用于将 32 位立即值加载到寄存器中。但它没有Store Immediate( SI)指令来将32位立即值存储到内存中。有人可以解释一下为什么吗?
assembly mips instruction-set immediate-operand instruction-encoding
我想使用 arm 组件将 1 个 32 位十六进制直接加载到寄存器中。
mov r1,#0x6c617669
Run Code Online (Sandbox Code Playgroud)
这不能使用,因为从这条指令我们只能加载 8 位值。所以我直接从内存中加载了 32 位值。那么如何将 32 位值存储在内存中并使用 arm 组件将其直接加载到寄存器中呢?
我试过这个代码。
.global main
main:
sub sp,sp,#4
str lr,[sp,#0]
sub sp,sp,#4
str r0,x
add sp,sp,#4
ldr lr,[sp,#0]
add sp,sp,#4
mov pc,lr
.data
x: .word 0x6c617669
Run Code Online (Sandbox Code Playgroud)
但给出以下错误。
test1.s: Assembler messages:
test1.s:45: Error: internal_relocation (type: OFFSET_IMM) not fixed up
Run Code Online (Sandbox Code Playgroud) 我有一个关于 AVX_mm256_blend_pd功能的问题。
我想优化我大量使用该_mm256_blendv_pd函数的代码。不幸的是,这具有相当高的延迟和低吞吐量。该函数将三个变量作为输入__m256d,其中最后一个变量表示用于从前 2 个变量中进行选择的掩码。
我发现了另一个函数(_mm256_blend_pd),它采用位掩码而不是__m256d变量作为掩码。当掩码是静态时,我可以简单地传递类似 0b0111从第一个变量中获取第一个元素和第二个变量中的最后 3 个元素的内容。然而,在我的例子中,掩码是使用_mm_cmp_pd返回__m256d变量的函数计算的。我发现我可以用来_mm256_movemask_pd从掩码返回一个 int ,但是当将其传递到函数中时_mm256_blend_pd我收到一个 error error: the last argument must be a 4-bit immediate。
有没有办法使用前 4 位来传递这个整数?或者是否有另一个类似于 movemask 的功能可以让我使用_mm256_blend_pd?或者我可以使用另一种方法来避免使用 cmp、movemask 和混合,这对于这个用例来说会更有效?
首先,我对movq和之间的区别有点困惑movabsq,我的教科书说:
常规movq指令只能具有可以表示为 32 位二进制补码的立即数源操作数。然后对该值进行符号扩展以生成目标的 64 位值。所述movabsq指令可以具有任意的64位立即值作为其源操作数,并且只能有一个寄存器作为目的地。
我有两个问题。
该movq指令只能具有可以表示为 32 位二进制补码的立即数源操作数。
所以这意味着我们不能做
movq $0x123456789abcdef, %rbp
Run Code Online (Sandbox Code Playgroud)
我们必须这样做:
movabsq $0x123456789abcdef, %rbp
Run Code Online (Sandbox Code Playgroud)
但是为什么movq被设计为不适用于 64 位立即数,这确实违背了q(四分字)的目的,我们需要movabsq为此目的而设置另一个,这不是很麻烦吗?
由于目标movabsq必须是寄存器,而不是内存,所以我们不能将 64 位立即数移动到内存中:
movabsq $0x123456789abcdef, (%rax)
Run Code Online (Sandbox Code Playgroud)
但有一个解决方法:
movabsq $0x123456789abcdef, %rbx
movq %rbx, (%rax) // the source operand is a register, not immediate constant, and the destination of movq can be memory
Run Code Online (Sandbox Code Playgroud)
那么为什么这条规则旨在让事情变得更难呢?
assembly x86-64 instruction-set cpu-architecture immediate-operand