使用以下c代码:
void insert(node ** tree, int val)
{
node *temp = NULL;
if(!(*tree))
{
temp = (node *)malloc(sizeof(node));
temp->left = temp->right = NULL;
temp->data = val;
*tree = temp;
return;
}
if(val < (*tree)->data)
{
insert(&(*tree)->left, val);
}
else if(val > (*tree)->data)
{
insert(&(*tree)->right, val);
}
}
我不知道如何从一个指向任何东西的指针开始,然后使用值,&amp; left,&amp; right创建另一个节点。换句话说,当遍历左侧节点的指针时,如何使当前指针指向左侧节点,然后向外指向,就好像指向左侧的同一个对象一样。
如何向左/向右移动?
right:
addi $a3, $a3, 8
jal build
or
right:
la a3, 8($a3)
jal build
答案 0 :(得分:1)
如果您使用裸机mips,则不会有操作系统来管理动态分配,因此您需要创建自己的分配器,或者只使用全局节点池。
如果您正在使用操作系统,只需调用相应的函数/系统调用。
您不能使用堆栈分配,因为当include()
超出范围时应释放该内存。
当你不知道如何做某事时,最简单的就是让gcc为你工作。
要输出可读但未注释的程序集,请使用
gcc -S -O0 src.c
要将原始C代码作为注释,但在反编译程序集中,请使用。
gcc -c src.c -g -O0
objdump -S src.o > out.S
通过手动比较两个输出,您可以很好地理解如何做某事。
在您的情况下,稍加修改的代码:
typedef struct node { int data; struct node * left; struct node * right; } node;
node node_pool[30];
node pool_index = 29;
void insert(node ** tree, int val)
{
node *temp = NULL;
if(!(*tree))
{
temp = &node_pool[pool_index];
temp->left = temp->right = NULL;
temp->data = val;
*tree = temp;
return;
}
if(val < (*tree)->data)
{
insert(&(*tree)->left, val);
}
else if(val > (*tree)->data)
{
insert(&(*tree)->right, val);
}
}
这是手动评论的程序集。请注意,它在函数调用中使用mips elf abi。
.comm node_pool,360,4
#node node_pool[30];
.globl pool_index
.data
.align 2
.type pool_index, @object
.size pool_index, 4
pool_index:
.word 29
#unsigned int pool_index = 29;
.text
.align 2
.globl insert
.set nomips16
.set nomicromips
.ent insert
.type insert, @function
insert:
.frame $fp,40,$31 # vars= 8, regs= 2/0, args= 16, gp= 8
.mask 0xc0000000,-4
.fmask 0x00000000,0
.set noreorder
.set nomacro
addiu $sp,$sp,-40
sw $31,36($sp)
sw $fp,32($sp)
move $fp,$sp
sw $4,40($fp)
sw $5,44($fp)
sw $0,24($fp)
#void insert(node ** tree, int val)
#{
lw $2,40($fp)
lw $2,0($2)
bne $2,$0,$L2
nop
#temp = &node_pool[pool_index--];
lui $2,%hi(pool_index)
lw $3,%lo(pool_index)($2)
move $2,$3
sll $2,$2,2
sll $4,$2,2
subu $4,$4,$2
lui $2,%hi(node_pool)
addiu $2,$2,%lo(node_pool)
addu $2,$4,$2
sw $2,24($fp)
addiu $3,$3,-1
lui $2,%hi(pool_index)
sw $3,%lo(pool_index)($2)
#temp->left = temp->right = NULL;
lw $2,24($fp)
sw $0,8($2)
lw $2,24($fp)
lw $3,8($2)
lw $2,24($fp)
sw $3,4($2)
lw $2,24($fp)
lw $3,44($fp)
sw $3,0($2)
lw $2,40($fp)
lw $3,24($fp)
sw $3,0($2)
j $L1
nop
#if(val < (*tree)->data){
$L2:
lw $2,40($fp)
lw $2,0($2)
lw $3,0($2)
lw $2,44($fp)
slt $2,$2,$3
beq $2,$0,$L4
nop
lw $2,40($fp)
lw $2,0($2)
addiu $2,$2,4
move $4,$2
lw $5,44($fp)
jal insert
nop
j $L1
nop
#insert(&(*tree)->left, val);
# }
$L4:
lw $2,40($fp)
lw $2,0($2)
lw $3,0($2)
lw $2,44($fp)
slt $2,$3,$2
beq $2,$0,$L1
nop
lw $2,40($fp)
lw $2,0($2)
addiu $2,$2,8
move $4,$2
lw $5,44($fp)
jal insert
nop
# else if(val > (*tree)->data){
# insert(&(*tree)->right, val);
# }
$L1:
move $sp,$fp
lw $31,36($sp)
lw $fp,32($sp)
addiu $sp,$sp,40
j $31
nop