使用指针而不是索引更新数组
Updating an array using pointers instead of indexing
我正在做一项作业,我们必须将一段 MIPS 代码翻译成 C(虽然即使您不了解 MIPS,也应该很容易理解这个问题,因为我已经提供了代码用 C 编写)。我无法联系我的老师,因为我们是一个庞大的 class 而且我知道他每天收到的电子邮件绰绰有余,这就是我转向这里的原因。
我正在尝试使用函数 copycodes() 将 text1 和 text2 中每个字符的 ascii 码复制到 list1 和 list2 中,以便它们可以通过提供的函数打印。
我基本上完成了,在我看来它应该可以工作,但是我不断收到 Segmentation fault (core dumped)-error,或者它只循环两次但是确实不打印列表中的任何内容。我一直在检查我的代码并更改一些小东西,但我一直在寻找一整天,但我似乎无法找到我的知识有缺陷的地方。
这个程序是我老师写的,除了函数copycodes(),函数work()和最上面的public变量。所有出现的注释(也在 mips 代码中)也是我写的。
如前所述,我还获得了表示应如何实施解决方案的 MIPS 代码,该代码已包含在下面代码中相应位置的注释中。我试图靠近 MIPS 代码,因此为什么 copycodes() 中的变量具有汇编代码使用的寄存器的名称。
这是我的做法:
#include <stdio.h>
//Assembly code:
/*
.data
text1: .asciiz "This is a string."
text2: .asciiz "Yet another thing."
.align 2
list1: .space 80
list2: .space 80
count: .word 0
*/
//C translation:
char* text1 = "This is a string.";
char* text2 = "Yet another thing.";
//int* list1;
//int* list2;
int list1 [80]; //Still passes the pointer of list1[0] to copycodes
int list2 [80];
int count = 0;
void printlist(const int* lst){
printf("ASCII codes and corresponding characters.\n");
while(*lst != 0){
printf("0x%03X '%c' ", *lst, (char)*lst);
lst++;
}
printf("\n");
}
void endian_proof(const char* c){
printf("\nEndian experiment: 0x%02x,0x%02x,0x%02x,0x%02x\n",
(int)*c,(int)*(c+1), (int)*(c+2), (int)*(c+3));
}
//Assembly code:
/*
copycodes:
loop:
# a0 is text (.asciiz)
# a1 is list (.space)
# a2 is count (.word)
lb $t0,0($a0) # byte t0 = from a0 (text1/text2)
beq $t0,[=10=],done # branch done if (t0 == 0)
sw $t0,0($a1) # else word t0 = a1 (list1/list2)
addi $a0,$a0,1 # a0++
addi $a1,$a1,4 # a1+4
lw $t1,0($a2) # load word from a2 into t1
addi $t1,$t1,1 # increment t1 by 1
sw $t1,0($a2) # store word from t1 to a2
j loop # jump to top
done:
jr $ra
*/
void copycodes(char* a0, int* a1, int* a2){
char t0 = *a0; //load byte from where a0 is pointing into t0)
while(t0 != 0) //until end of string
{
//sw $t0,0($a1) // else word t0 = a1 (list1/list2)
//t0 = *a1;
*a1 = t0; //store word from t0 to where a1 is pointing )
//addi $a0,$a0,1 // a0++
//addi $a1,$a1,4 // a1+4
a0++; //increments pointer of text (a0)
a1 += 4; //increments pointer of list (a1) (in the mips code this is incremented by 4)
//lw $t1,0($a2) // load word from t1 into a2
//addi $t1,$t1,1 // increment t1 by 1
//sw $t1,0($a2) // store word from t1 to a2
int countValue = *a2; //set countValue equal to value at pointer a2
countValue++; //increment counter
*a2 = countValue; // Set counter (at register a2) to the incremented value
}
}
void work(){
copycodes(text1,list1,&count);
copycodes(text2,list2,&count);
}
int main(void){
work();
printf("\nlist1: ");
printlist(list1); //[20]);
printf("\nlist2: ");
printlist(list2); //);
printf("\nCount = %d\n", count);
endian_proof((char*) &count);
}
我见过类似的问题,例如Homework: Making an array using pointers
但在我看来,好像他们在指针方面做的事情基本上是一样的?我想了一会儿,也许我的问题是我增加 a0 和 a1 的数量,但我还没有找到任何描述这个问题的东西。
编辑:
我不妨补充一下,所需的输出是:
list1:ASCII码及对应的字符。 0x054'T'0x068'h'0x069'i'0x073's'0x020''0x069'i'0x073's'0x020''0x061'a'0x020' ' 0x073 's' 0x074 't' 0x072 'r' 0x069 'i' 0x06E 'n' 0x067 'g' 0x02E '.'
list2:ASCII码和对应的字符。 0x059 'Y' 0x065 'e' 0x074 't' 0x020 ' ' 0x061 'a' 0x06E 'n' 0x06F 'o' 0x074 't' 0x068 'h' 0x065 'e' 0x072 'r' 0x020 ' ' 0x074 't' 0x068 'h' 0x069 'i' 0x06E 'n' 0x067 'g' 0x02E '.'计数 = 35
字节序实验:0x23,0x00,0x00,0x00
非常感谢 melpomene 和 Dmitri 发现问题!
我确实错误地增加了 a1 并且也忘记了在 while 循环中更新 t0。我最终得到了一个完全没有 t0 的解决方案。
这是更新后的函数:
void copycodes(char* a0, int* a1, int* a2){
//char t0 = *a0; //load byte from where a0 is pointing into t0)
while(*a0 != 0) //until end of string
{
//sw $t0,0($a1) // else word t0 = a1 (list1/list2)
//t0 = *a0;
*a1 = *a0; //store word from t0 to where a1 is pointing )
//addi $a0,$a0,1 // a0++
//addi $a1,$a1,4 // a1+4
a0++; //increments pointer of text (a0)
a1++; //increments pointer of list (a1) (in the mips code this is incremented by 4)
//lw $t1,0($a2) // load word from t1 into a2
//addi $t1,$t1,1 // increment t1 by 1
//sw $t1,0($a2) // store word from t1 to a2
int countValue = *a2; //set countValue equal to value at pointer a2
countValue++; //increment counter
*a2 = countValue; // Set counter (at register a2) to the incremented value
}
}
我正在做一项作业,我们必须将一段 MIPS 代码翻译成 C(虽然即使您不了解 MIPS,也应该很容易理解这个问题,因为我已经提供了代码用 C 编写)。我无法联系我的老师,因为我们是一个庞大的 class 而且我知道他每天收到的电子邮件绰绰有余,这就是我转向这里的原因。
我正在尝试使用函数 copycodes() 将 text1 和 text2 中每个字符的 ascii 码复制到 list1 和 list2 中,以便它们可以通过提供的函数打印。
我基本上完成了,在我看来它应该可以工作,但是我不断收到 Segmentation fault (core dumped)-error,或者它只循环两次但是确实不打印列表中的任何内容。我一直在检查我的代码并更改一些小东西,但我一直在寻找一整天,但我似乎无法找到我的知识有缺陷的地方。
这个程序是我老师写的,除了函数copycodes(),函数work()和最上面的public变量。所有出现的注释(也在 mips 代码中)也是我写的。
如前所述,我还获得了表示应如何实施解决方案的 MIPS 代码,该代码已包含在下面代码中相应位置的注释中。我试图靠近 MIPS 代码,因此为什么 copycodes() 中的变量具有汇编代码使用的寄存器的名称。
这是我的做法:
#include <stdio.h>
//Assembly code:
/*
.data
text1: .asciiz "This is a string."
text2: .asciiz "Yet another thing."
.align 2
list1: .space 80
list2: .space 80
count: .word 0
*/
//C translation:
char* text1 = "This is a string.";
char* text2 = "Yet another thing.";
//int* list1;
//int* list2;
int list1 [80]; //Still passes the pointer of list1[0] to copycodes
int list2 [80];
int count = 0;
void printlist(const int* lst){
printf("ASCII codes and corresponding characters.\n");
while(*lst != 0){
printf("0x%03X '%c' ", *lst, (char)*lst);
lst++;
}
printf("\n");
}
void endian_proof(const char* c){
printf("\nEndian experiment: 0x%02x,0x%02x,0x%02x,0x%02x\n",
(int)*c,(int)*(c+1), (int)*(c+2), (int)*(c+3));
}
//Assembly code:
/*
copycodes:
loop:
# a0 is text (.asciiz)
# a1 is list (.space)
# a2 is count (.word)
lb $t0,0($a0) # byte t0 = from a0 (text1/text2)
beq $t0,[=10=],done # branch done if (t0 == 0)
sw $t0,0($a1) # else word t0 = a1 (list1/list2)
addi $a0,$a0,1 # a0++
addi $a1,$a1,4 # a1+4
lw $t1,0($a2) # load word from a2 into t1
addi $t1,$t1,1 # increment t1 by 1
sw $t1,0($a2) # store word from t1 to a2
j loop # jump to top
done:
jr $ra
*/
void copycodes(char* a0, int* a1, int* a2){
char t0 = *a0; //load byte from where a0 is pointing into t0)
while(t0 != 0) //until end of string
{
//sw $t0,0($a1) // else word t0 = a1 (list1/list2)
//t0 = *a1;
*a1 = t0; //store word from t0 to where a1 is pointing )
//addi $a0,$a0,1 // a0++
//addi $a1,$a1,4 // a1+4
a0++; //increments pointer of text (a0)
a1 += 4; //increments pointer of list (a1) (in the mips code this is incremented by 4)
//lw $t1,0($a2) // load word from t1 into a2
//addi $t1,$t1,1 // increment t1 by 1
//sw $t1,0($a2) // store word from t1 to a2
int countValue = *a2; //set countValue equal to value at pointer a2
countValue++; //increment counter
*a2 = countValue; // Set counter (at register a2) to the incremented value
}
}
void work(){
copycodes(text1,list1,&count);
copycodes(text2,list2,&count);
}
int main(void){
work();
printf("\nlist1: ");
printlist(list1); //[20]);
printf("\nlist2: ");
printlist(list2); //);
printf("\nCount = %d\n", count);
endian_proof((char*) &count);
}
我见过类似的问题,例如Homework: Making an array using pointers 但在我看来,好像他们在指针方面做的事情基本上是一样的?我想了一会儿,也许我的问题是我增加 a0 和 a1 的数量,但我还没有找到任何描述这个问题的东西。
编辑: 我不妨补充一下,所需的输出是:
list1:ASCII码及对应的字符。 0x054'T'0x068'h'0x069'i'0x073's'0x020''0x069'i'0x073's'0x020''0x061'a'0x020' ' 0x073 's' 0x074 't' 0x072 'r' 0x069 'i' 0x06E 'n' 0x067 'g' 0x02E '.'
list2:ASCII码和对应的字符。 0x059 'Y' 0x065 'e' 0x074 't' 0x020 ' ' 0x061 'a' 0x06E 'n' 0x06F 'o' 0x074 't' 0x068 'h' 0x065 'e' 0x072 'r' 0x020 ' ' 0x074 't' 0x068 'h' 0x069 'i' 0x06E 'n' 0x067 'g' 0x02E '.'计数 = 35
字节序实验:0x23,0x00,0x00,0x00
非常感谢 melpomene 和 Dmitri 发现问题!
我确实错误地增加了 a1 并且也忘记了在 while 循环中更新 t0。我最终得到了一个完全没有 t0 的解决方案。
这是更新后的函数:
void copycodes(char* a0, int* a1, int* a2){
//char t0 = *a0; //load byte from where a0 is pointing into t0)
while(*a0 != 0) //until end of string
{
//sw $t0,0($a1) // else word t0 = a1 (list1/list2)
//t0 = *a0;
*a1 = *a0; //store word from t0 to where a1 is pointing )
//addi $a0,$a0,1 // a0++
//addi $a1,$a1,4 // a1+4
a0++; //increments pointer of text (a0)
a1++; //increments pointer of list (a1) (in the mips code this is incremented by 4)
//lw $t1,0($a2) // load word from t1 into a2
//addi $t1,$t1,1 // increment t1 by 1
//sw $t1,0($a2) // store word from t1 to a2
int countValue = *a2; //set countValue equal to value at pointer a2
countValue++; //increment counter
*a2 = countValue; // Set counter (at register a2) to the incremented value
}
}