在64位汇编中编写函数

时间:2014-10-31 09:59:08

标签: c assembly

我试图在64位汇编中编写一个函数(max),我不知道我做错了什么,也许你们中的一些人可以确定我做错了什么:/

这是功能:

int max(int a, int b) {
/* Return the larger of the two integers `a' and `b'. */
if (a > b)
return a;
else
return b;
}

这是我的汇编代码(带注释):

    push %rbp
    mov %rsp, %rbp
    mov %rdi, %rax
    mov %rsi, %rcx
    test %rax, %rax                // Checking if first parameter is signed
    js .signedRAX
    test %rcx, %rcx                // Checking if second parameter is signed
    js .signedRCX
    jmp .compare                   // If either one signed then jump to .compare
  .signedRAX:
    test %rcx, %rcx                // Checking if both are signed
    js .signedRAXandRCX
    mov %rcx, %rax                 // If not then return the positive number
    jmp .end                       // finish the function
  .signedRCX:
    jmp .end                       // If only the second parameter is signed then jump  
  .signedRAXandRCX:                // straight to end of function and return %rax
    cmp %rax, %rcx                 // If both are signed compare which one is the max
    jl .end 
    mov %rcx, %rax
    jmp .end
  .compare:
    cmp %rax, %rcx                 // If both are positive then compare which one is 
    jg .end                        // the max
    mov %rcx, %rax
  .end:
    mov %rbp, %rsp
    pop %rbp
    ret

在比较两个已签名且均为正数的参数时,输出错误。

2 个答案:

答案 0 :(得分:2)

你的工作太复杂了。

如果我将您的计划输入gcc -S,我会

max:
.LFB0:
        .cfi_startproc
        pushl   %ebp
        .cfi_def_cfa_offset 8
        .cfi_offset 5, -8
        movl    %esp, %ebp
        .cfi_def_cfa_register 5
        movl    8(%ebp), %eax
        cmpl    12(%ebp), %eax
        jle     .L2
        movl    8(%ebp), %eax
        jmp     .L3
.L2:
        movl    12(%ebp), %eax
.L3:
        popl    %ebp
        .cfi_restore 5
        .cfi_def_cfa 4, 4
        ret
        .cfi_endproc
.LFE0:

如果我接管你的" ABI"以及传递参数的方式,

我得到了

max:
    push %rbp
    mov %rsp, %rbp
    mov %rdi, %rax
    mov %rsi, %rcx
    cmpl %rcx, %rax
    jle .L2
    movl %rcx, %rax
.L2:
    mov %rbp, %rsp
    pop %rbp
    ret

答案 1 :(得分:0)

这是来自问题的ASM的等效C伪代码。您可以看到,对于a >= 0b < 0,它会返回b。对于a < 0b >= 0,它会返回a。那是不对的。代码中可能存在其他错误,因为编码的操作非常简单。代码中很难看到任何内容。不要让简单的事情如此复杂。遵循KISS原则。

// test %rax, %rax
// js .signedRAX
if (a >= 0) {
    // test %rcx, %rcx
    // js .signedRCX
    if (b >= 0) {
        // .compare
        // cmp %rax, %rcx                 // If both are positive then compare which one is 
        // jg .end                        // the max
        if (a > b) {
            b = a;
        }
        return b;
    } else {
        // .signedRCX
        return b;
    }
} else {
    // .signedRAX
    // test %rcx, %rcx                // Checking if both are signed
    // js .signedRAXandRCX
    if (b >= 0) {
        b = a;
        return b;
    } else {
        // .signedRAXandRCX
        // cmp %rax, %rcx                 // If both are signed compare which one is the max
        // jl .end
        if (a < b) {
            b = a;
        }
        return b;
    }
}