如何在MIPS程序集中的二进制搜索树节点中构建树?

时间:2016-03-30 01:12:01

标签: mips

使用以下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

1 个答案:

答案 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