- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
for(int i = 0; i < 6; i++) {
int temp = pos[i];
x[temp] = data[i];
}
假设我已经在 mips 中创建了数组,那么,
main: la $s1, x ## load address of x into $s1
la $s2, pos # load address of pos into $s2
la $s3, data # load address of data into $s3
li $s6, 6 # for loop test.
li $s0, 0 # i variable
这就是我尝试将两行 C++ 翻译成 mips 的方式,
add $t1, $s2, $s0 # Get pos[i] and put in $t1;
sw $t1, ($t3) # int temp = pos[i]
add $t2, $s3, $s0 # Get data[i] and put in #t2
add $t4, $s1, $t3 # Get x[temp] and store it in $t4
sw $t2, ($t4) # x[temp] = data[i];
addi $s0, $s0, 1 # i++
blt $s0, $s6, for # (for i < 6)
然而,当我在 qtspim 上运行它时(当与完整代码结合时),我最终得到的输出是
0000000000
代替
07304700230026
我应该得到什么...我做错了什么?谢谢。
最佳答案
您的一些基本结构是正确的,并且有很好的评论。
但是,在初始化值方面存在一些错误,使用了错误的寄存器并且实际上没有从内存中获取。此外,索引值必须转换为字节偏移量。
我已经为您的程序制作了两个版本。带有错误注释的版本。并且,一个清理后的工作版本。
这是注释版本[请原谅不必要的样式清理]:
main:
la $s1,x # load address of x into $s1
la $s2,pos # load address of pos into $s2
la $s3,data # load address of data into $s3
li $s6,6 # for loop test.
li $s0,0 # i variable
# This is how I tried translating the two lines of C++ into mips,
for:
# NOTE/BUG: for the index values, when adding them to the base address
# of a given array, we need a _byte_ offset (i.e. the index multiplied by
# 4)
# NOTE/BUG: this does _not_ fetch pos[i] from memory -- it merely puts "i"
# into the target
add $t1,$s2,$s0 # Get pos[i] and put in $t1;
# NOTE/BUG: $t3 is never initialized to anything
sw $t1,($t3) # int temp = pos[i]
# NOTE/BUG: this does _not_ fetch pos[i] from memory -- it merely puts "i"
# into the target
add $t2,$s3,$s0 # Get data[i] and put in #t2
# NOTE/BUG: $t3 should contain an _index_ value -- it would have to be
# multiplied by 4 to create a _byte_ offset
add $t4,$s1,$t3 # Get x[temp] and store it in $t4
sw $t2,($t4) # x[temp] = data[i];
addi $s0,$s0,1 # i++
blt $s0,$s6,for # (for i < 6)
这是清理后的版本。我添加了缺失的代码,使其成为一个完整的可运行程序。我试图尽可能多地保留您的原始代码,但不幸的是,我不得不重构它:
.text
.globl main
#
# for (int i = 0; i < 6; i++) {
# int temp = pos[i];
# x[temp] = data[i];
# }
main:
la $s1,x # load address of x into $s1
la $s2,pos # load address of pos into $s2
la $s3,data # load address of data into $s3
li $s6,6 # for loop test.
li $s0,0 # i variable
la $a0,msg_pos
move $a1,$s2
jal print
la $a0,msg_data
move $a1,$s3
jal print
for:
sll $t0,$s0,2 # get byte offset for pos/data
addu $t1,$s2,$t0 # get address of pos[i]
lw $t1,0($t1) # get value of pos[i] (i.e. temp)
bltz $t1,next # skip negative indexes
bge $t1,6,next # skip indexes that overflow
sll $t1,$t1,2 # convert temp to byte offset
addu $t1,$s1,$t1 # get address of x[temp]
addu $t2,$s3,$t0 # get address of data[i]
lw $t2,0($t2) # get value of data[i]
sw $t2,0($t1) # x[temp] = data[i]
next:
addi $s0,$s0,1 # i++
blt $s0,$s6,for # (for i < 6)
la $a0,msg_x
move $a1,$s1
jal print
li $v0,10
syscall
# print -- print array
#
# arguments:
# a0 -- message pointer
# a1 -- array pointer
print:
li $a2,6
li $v0,4
syscall
print_loop:
li $v0,4
la $a0,msg_space
syscall
li $v0,1
lw $a0,0($a1)
syscall
addiu $a1,$a1,4
addi $a2,$a2,-1
bgtz $a2,print_loop
li $v0,4
la $a0,msg_nl
syscall
jr $ra
.data
pos: .word 5, 0, 4, 1, 3, 2
data: .word 1, 2, 3, 4, 5, 6
x: .word -1, -1, -1, -1, -1, -1
msg_pos: .asciiz "pos:"
msg_data: .asciiz "data:"
msg_x: .asciiz "x:"
msg_space: .asciiz " "
msg_nl: .asciiz "\n"
编辑:虽然不是您的原始代码的一部分,但我在 temp
上添加了边界检查,因为它是所问的类似问题的一部分并且无论如何都很有意义。
关于c++ - 将这些 C++ 行转换为汇编/mips 时,我做错了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39713231/
我试图在图形模式下打印一个字符。通常当我打印我正在做的一个字符时: mov ah,14 ; ah=14 mov al,'x' int 10h ; print the character 这
我试图通过更改其中的一个字节来修改存储在内存中的字符串。我为此使用了 movb,但由于某种原因,给定内存位置的字节没有改变。 在 gdb 调试器上: 14 movb %al, (%r10) # nex
我一直在阅读一些汇编代码,并且开始发现调用指令实际上是与程序计数器相关的。 但是,每当我使用 Visual Studio 或 Windbg 进行调试时,它总是显示 call 0xFFFFFF ...这
我最近一直在使用 Visual C++ 中的内联汇编,我想知道是否可以直接向堆栈上的局部变量添加值,例如: push 5 add [esp], 7 这样做可以吗?我问这个问题是因为我在执行此操作时随机
我有下一个代码: mov al, -5 add al, 132 add al, 1 据我检查,溢出标志和进位标志将在第一个操作中设置,而在第二个操作中,仅设置溢出。 但我不明白为什么: 在无符号数中,
在 64 位 x86 汇编 nasm 中,如何将单个字节从寄存器移动到 .data 节中定义的内存位置? 我知道这有效 global _main section .data quotient db 0
我的汇编代码有问题。我想打印存储在寄存器 cx 中的数字,但是当我尝试打印它时,它打印的是 ascii 字符而不是 ascii 数字,所以我决定编写一个程序将 ascii char 转换为 ascii
为什么第 1B 行的跳转指令(例如)变成了 EBBD? 我知道“jmp”= EB但是BD是怎么计算的呢? 最佳答案 短跳转使用一个带符号的偏移量添加到 JMP 之后的指令地址。 例如,第一个 JMP
以下两者有什么区别: mov eax, [eax+4] 和 add eax, 4 mov eax, [eax] 如果不是,那么汇编器是否会选择哪个来进行某种优化? 最佳答案 这
看《The Shellcoder's Handbook》中的一些汇编和反汇编代码,发现一条指令的序列操作数是不一样的。 例如,在 assembly 上: mov ebx,0 并且,在反汇编时: mov
我有这个非常简单的汇编代码: start: add ax, 100 ; if ax overflow add to bx 1 jmp start 但我不知道如何检测 ax 寄存器溢出,有人可以帮
在 64 位 x86 汇编 nasm 中,如何将单个字节从寄存器移动到 .data 节中定义的内存位置? 我知道这有效 global _main section .data quotient db 0
我的汇编代码有问题。我想打印存储在寄存器 cx 中的数字,但是当我尝试打印它时,它打印的是 ascii 字符而不是 ascii 数字,所以我决定编写一个程序将 ascii char 转换为 ascii
我正在学习一些关于操作系统开发的教程,我发现了一篇关于多重引导 header 。这些是您必须定义的一些“神奇”值才能使用GRUB2。这些是命令: # Declare constants used f
为什么第 1B 行的跳转指令(例如)变成了 EBBD? 我知道“jmp”= EB但是BD是怎么计算的呢? 最佳答案 短跳转使用一个带符号的偏移量添加到 JMP 之后的指令地址。 例如,第一个 JMP
我正在尝试从内存中复制一些单词并使用汇编将其保存到另一个内存地址。我正在尝试为其编写代码,但我不确定其中的某些部分。我将简要描述我想要做什么。 源地址、目标地址和要复制的字数是函数的输入参数。 最佳答
当我们想要像这样创建一个初始化变量时: name db 'zara ali' 我们创建了一个字节大小变量,但我们在其中存储了一个字符串 这怎么可能?? 当我们使用这条指令时: MOV ecx, nam
我还是汇编的新手,我还不知道汇编中的许多命令代码。我想在 16 位寄存器中进行除法。我想打印它的内容。我知道我需要将寄存器的内容转换为 ASCII 进行打印,但同样,我的问题是除法。请帮我。 比如cx
使用有什么区别: c.eq.s $1, $2 bc1t L2 并使用: beq $1, $2, L2 如果他们做同样的事情,为什么有两种分支方式?如果它们不同,那么它们各自的好处是什么
源代码: int main() { int i; for(i=0, i : push rbp 2. 0x000055555555463b :
我是一名优秀的程序员,十分优秀!