gpt4 book ai didi

c - 将值从 C 程序传递到汇编语言

转载 作者:IT王子 更新时间:2023-10-29 00:31:29 27 4
gpt4 key购买 nike

我想使用链接程序集方法而不是 C 中的内联程序集方法将值从 C 程序传递到程序集。下面是正在开发的汇编程序(GCD)。

;gcdasm.nasm
bits 64
section .text
global gcdasm
gcdasm:
push rbp
mov rbp, rsp
mov rax, [rbp+4] ;load rax with x
mov rbx, [rbp+8] ;load rbx with y
top:
cmp rax, rbx ;x(rax) has to be larger than y(rbx)
je exit ;if x=y then exit and return value y
jb xchange ;if x<y then swap x and y
modulo:
cqo ;RDX:RAX sign extend
div rbx ;div rdx:rax with rbx
cmp rdx, 0 ;check remider if its 0
je exit ;if reminder is 0 then exit return return y
mov rax, rdx ;reminder rdx as next dividend
jmp modulo ;loop
xchange:
xchg rax, rbx ;swap x and y
jmp modulo

exit:
mov rax, rbx ;Return c program with the divisor y
mov rsp, rbp
pop rbp
ret

这是我尝试将值传递给汇编程序的 C 程序

//gcd.c
#include<stdio.h>

extern int gcdasm(int x, int y);

int main(void){
int x=0;
int y=0;
int result=0;

x = 46;
y = 90;
printf("%d and %d have a gcd of %d\n", x,y,gcdasm(x,y));

x = 55;
y = 66;
printf("%d and %d have a gcd of %d\n", x,y,gcdasm(x,y));

return 0;
}

当我使用下面的方法编译并运行它时。我收到错误 Floating point exception 或等待输入的空提示

$ nasm -felf64 gcdasm.nasm -o gcdasm.o
$ gcc gcdasm.o gcd.c -o gcd
$ ./gcd
Floating point exception
$ ./gcd

我无法找出错误。请帮帮我。谢谢你。

最佳答案

将参数传递给 gcdasm()

两个int 参数是通过寄存器而不是堆栈传递的。第一个和第二个参数在 rdirsi 的下半部分传递(即:ediesi ), 分别。因此,通过将 ediesi 符号分别扩展到 raxrbx 中,您可以将传递的参数加载到这些寄存器中:

movsx rax, edi  ;load rax with x
movsx rbx, esi ;load rbx with y

但是请注意,rbx 不是一个暂存器,因此被调用者需要在修改之前保存它,然后再恢复它在离开 gcdasm 函数之前。

您可以简单地将代码中的所有位置的 rbx 替换为 rcx(这不是一个callee-saved 寄存器)。您根本不需要 rbp,因此您可以删除出现 rbp 的所有指令。


其他问题

  • 程序逻辑也有问题:

    mov rax, rdx   ;reminder rdx as next dividend

    取而代之的是,除数 (rcx) 应该变成股利 (rax) 和 < em>余数 (rdx) 应成为除数 (rcx),即:

    mov rax, rcx
    mov rcx, rdx
  • signed值时,必须使用idiv指令,而不是div


改进

对于 comparing rdx against zero,使用 test rdx, rdx 而不是 cmp rdx, 0 也有一些关于性能和代码大小的原因。 .


考虑到以上所有内容:

;gcdasm.nasm
bits 64
section .text
global gcdasm
gcdasm:
movsx rax, edi ;load rax with x
movsx rcx, esi ;load rcx with y
top:
cmp rax, rcx ;x(rax) has to be larger than y(rcx)
je exit ;if x=y then exit and return value y
jb xchange ;if x<y then swap x and y
modulo:
cqo ;sign extend RDX:RAX
idiv rcx ;rdx:rax/rcx (signed values)
test rdx, rdx ;check whether remainder is zero
je exit ;if reminder is 0 then exit return y
mov rax, rcx ;divisor becomes dividend
mov rcx, rdx ;remainder becomes divisor
jmp modulo ;loop
xchange:
xchg rax, rcx ;swap x and y
jmp modulo

exit:
mov rax, rcx ;Return c program with the divisor y
ret

关于c - 将值从 C 程序传递到汇编语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48899696/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com