首页 > 解决方案 > ASM x64 函数指针未返回正确值

问题描述

我在汇编中遇到函数指针问题,即使我的函数返回一个负数,它总是设置rax为一个正数,我用一个比较两个整数的函数做了一个最小的可复制示例,它做同样的事情:

ASM 功能代码[编辑]:

global foo

section .data
msg: db `superior\n`
msg_len: equ $-msg

section .text
foo:
    push rbx
    mov rbx, rdi
    mov rdi, 2
    mov rsi, 1
    sub rsp, 8  ; align the stack frame
    call rbx
    add rsp, 8
    test rax, rax   ;[EDIT] correct: test eax, eax
    js  bar
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, msg_len
    syscall

bar:
    mov rdi, 1
    mov rsi, 2
    sub rsp, 8  ; same here
    call rbx
    add rsp, 8
    test rax, rax  ;[EDIT] correct: test eax, eax
    js exit
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, msg_len
    syscall

exit:
    pop rbx   ;restoring initial data of rbx
    ret

main.c 代码:

#include <stdio.h>

int foo(int (*f)());  //my asm function prototype

int cmp(int i, int j)
{
  printf("%d - %d\n", i, j);
  return(i - j);
}

int main(void)
{
  foo(&cmp);
  return (0);
}

输出是:

2 - 1
superior
1 - 2
superior

但它应该只是:

2 - 1
superior

汇编:

nasm -f elf64 foo.s
gcc -c main.c -o main.o
gcc main.o foo.o

谢谢您的帮助

[编辑] 它不起作用,因为我检查了 rax 而不是 eax,现在它起作用了。谢谢你的帮助

标签: cassemblyx86-64nasmfunction-pointers

解决方案


Anint是 32 位,但是rax是一个 64 位的寄存器。返回的函数int会将其返回值放入 中eax,这通常会将 的高半部分归零rax。因此,如果cmp返回-132 位数字0xffffffffrax则将包含0x00000000ffffffff. 这不是一个负的 64 位数字,因此test rax, rax不会设置符号标志。

尝试使用test eax, eax作为您的测试。


推荐阅读