【问题标题】:How to convert C code to MIPS assembly?如何将 C 代码转换为 MIPS 程序集?
【发布时间】:2023-03-20 11:57:02
【问题描述】:

我目前正在为一个需要我将 C 程序转换为 MIPS 程序集的类编写程序。前提是取两个十六进制值,看看有多少个 1 在二进制中匹配。例如,这里是 C 代码:

// Count the number of items that match the pattern (have '1' bits in 
// the same place as the pattern)
// pu32_a points to the first element of the array
// u32_n is the number of elements in the array
// u32_pat is the pattern to match

uint32_t pmatch(uint32_t* pu32_a, uint32_t u32_n, uint32_t u32_pat) {

  uint32_t u32_result;

  u32_result = 0;
  while(u32_n != 0) {
    if((*pu32_a & u32_pat) == u32_pat) u32_result++;
    pu32_a++;
    u32_n--;
  }

return u32_result;

}

uint32_t au32_k[] = {0x80000000, 0xFFFFFFFF, 0x0000A5AA, 0xF0F0F0F0};
uint32_t u32_count;

main() {

  u32_count = pmatch(au32_k, 4, 0x0000000F0);
  printf("Number of matches is: %d \n", u32_count);

}  

这是我当前的汇编代码:

#
#
# au32_k = {0x80000000, 0xFFFFFFFF,
#       0x0000A5AA, 0xF0F0F0F0}
#
#

         .data
au32_k:  .space 16
u32_n:   .word  4
u32_pat: .word  240
         .text

main:

    # Store values in $s# registers

    addi $s0, $zero, 2147483648
    addi $s1, $zero, 4294967295
    addi $s2, $zero, 42410
    addi $s3, $zero, 4042322160

    # Index = $t0
    # This loads each of the values into an array
    # starting at index $t0.

    addi $t0, $zero, 0
    sw   $s0, au32_k($t0)
    addi $t0, $t0, 4
    sw   $s1, au32_k($t0)
    addi $t0, $t0, 4
    sw   $s2, au32_k($t0)
    addi $t0, $t0, 4
    sw   $s3, au32_k($t0)

    # Reset pointer to 0

    addi $t0, $t0, -12

    # Storing values in argument registers for subroutine

    la $a0, au32_k
    lw $a1, u32_n
    lw $a2, u32_pat
    jal pmatch

# This is where I get completely lost.

pmatch:

    addi $s0, $zero, 0
    addi $s1, $zero, 0

    while:

        beqz $a1, while_end

        if_start:

    while_end:

我完全迷失在 C 代码中的这一部分:

if((*pu32_a & u32_pat) == u32_pat) u32_result++;

我不知道如何将其转换为汇编,坦率地说,不知道这是如何计算两个数字中匹配 1 位的数量。

【问题讨论】:

    标签: c assembly mips mips32 language-translation


    【解决方案1】:

    我不会为你完成整个任务,但这就是代码的作用。

    if((*pu32_a & u32_pat) == u32_pat) u32_result++;
    

    第一个重要的块是这样的:

    (*pu32_a & u32_pat)
    

    它涉及取消引用名为pu32_a 的指针变量。然后将其与另一个名为 u32_pat 的变量进行“与”运算。接下来的chunk如下。

     == u32_pat) u32_result++;
    

    此块将 AND 操作的结果与名为 u32_pat 的变量进行比较。如果相等,则名为u32_result 的变量加一。

    【讨论】:

    • 我的意思是,是的。我明白那部分。我不明白的是,如果我有 2 个二进制数(11110000111100001111000011110000、00000000000000000000000011110000),则此代码最终会生成 u32_result = 4,因为这两个二进制数中有 4 个匹配的 1。我觉得我必须一点一点地向右移动并检查 LSB 是否匹配。我不明白该怎么做。
    • @LandonHaugh 我真的不能为你完成你的任务。这必须由您完成并理解。如果不帮助你作弊,我就无能为力了。 :L
    • 你们两个可能对这里描述的折衷方案感兴趣。 meta.stackoverflow.com/questions/334822/…
    • @LandonHaugh 该函数不计算匹配的 1。因此,您无需换班。
    • 赞成鼓励 OP 在提示后重试。
    猜你喜欢
    • 1970-01-01
    • 2021-09-13
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    相关资源
    最近更新 更多