c - 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,现在它起作用了。谢谢你的帮助
解决方案
Anint
是 32 位,但是rax
是一个 64 位的寄存器。返回的函数int
会将其返回值放入 中eax
,这通常会将 的高半部分归零rax
。因此,如果cmp
返回-1
32 位数字0xffffffff
,rax
则将包含0x00000000ffffffff
. 这不是一个负的 64 位数字,因此test rax, rax
不会设置符号标志。
尝试使用test eax, eax
作为您的测试。
推荐阅读
- python-3.x - 如何从 KMeans 集群中获取集群的名称?
- node.js - 如何将 npm 根路径设置为 .../Appdata/roaming/npm
- mysql - mySQL 中的集合和表有什么区别?
- angular - 将按钮添加到 ag-grid 列标题
- android - 从 json 响应中删除符号 
- javascript - 量角器:模拟 angularjs 属性
- node.js - Node.JS 如何将 ISO-8859-1 解码为 UTF-8?
- php - 图像转换成字符串并返回
- spring - 为什么 Spring WebFlux ServerResponse 没有泛型类型的主体
- java - 我可以使用 bin 文件夹中的 .class 文件取回我的 SRC 文件吗?