- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我想使用链接程序集方法而不是 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
参数是通过寄存器而不是堆栈传递的。第一个和第二个参数在 rdi
和 rsi
的下半部分传递(即:edi
和 esi
), 分别。因此,通过将 edi
和 esi
符号分别扩展到 rax
和 rbx
中,您可以将传递的参数加载到这些寄存器中:
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/
我不确定 cbw命令实际上可以。我有一段代码: mov ax,0FF0h cbw idiv ah cbw后ax的值如何变化? 最佳答案 cbw指令将一个字节符号扩展为一个字。在这种情况下,它将采用
MIPS 架构中的.s 和.asm 有什么区别? 最佳答案 .s 和.asm 之间没有天生的区别 如果你愿意,你可以用 .s 命名文本文件,用 .asm 命名十六进制文件,但这只是为了让它们保持正直。
我正在业余时间学习汇编语言,以成为更好的开发人员。 我在概念层面上理解基于堆栈的机器和基于寄存器的机器之间的区别,但我想知道基于堆栈的机器实际上是如何实现的。如果是虚拟机,例如JVM 或 .NET,在
几周后我开始上大学(软件工程学位),并且知道我将在第一年学习的一个模块是“建筑基础”或类似的东西;基本上它是在学习“汇编”中的编程。 我想做一些背景学习,所以我为此做好了准备(我在其他一些单元上做了同
我是汇编语言的新手。我目前正在经历这个 Assembly Guide .我对 LEA 指令有疑问。我对LEA指令的理解是LEA用source operand的有效地址加载destination ope
x86 汇编中是否有模运算符或指令之类的东西? 最佳答案 如果您的模数/除数是一个已知常数,并且您关心性能,请参阅 this和 this .对于直到运行时才知道的循环不变值,乘法逆甚至是可能的,例如见
我是汇编语言的新手。我目前正在经历这个 Assembly Guide .我对 LEA 指令有疑问。我对LEA指令的理解是LEA用source operand的有效地址加载destination ope
我相信这对大多数人来说非常简单,但我对 x86 汇编语言不是很熟悉。我只是想自学。 我在 window 里。在我读到的任何地方,我都被告知要使用 INT 21返回操作系统。这退出了程序,但我收到一条错
我正在尝试输入一个字符串,然后查看该字符串中的最后一个值是否为 EOL 字符。我想我会使用读入的字符串的长度,然后将它添加到缓冲区的地址以找到最后一个元素。这似乎不起作用。 编辑:很抱歉我没有包含更多
; This program checks for even or odd parities inside of an array. Displays 1 if even or 0 if odd. I
我一直在努力掌握 x86 汇编语言,并且想知道是否有一个与 movl $1, %eax 等效的快速简短的语言。就在那时,我认为列出该语言中经常使用的习语可能是个好主意。 这可能包括首选使用 xorl
有人知道如何在 ARMv6 汇编语言中开始注释(例如“#”、“;”、“/”、“/*”)吗? 最佳答案 应该是“;”根据我在 wikipedia article: 上找到的一些示例代码 loop
; This program checks for even or odd parities inside of an array. Displays 1 if even or 0 if odd. I
我是一名利用业余时间学习汇编语言的大学生。我注意到虽然有像 add 和 mul 这样的指令,但算术运算符经常在指令中使用。例如: mov eax,[ebx+ecx] 它等价于以下吗? add ebx,
我真的是学习汇编语言的新手,并且刚刚开始研究汇编语言,所以我想知道也许有些人可以帮助我解决一个问题。我有一个作业,告诉我将汇编语言指令与C代码进行比较,并告诉我哪些C代码与汇编指令等效。所以这是组装说
假设我有以下代码: C++ 代码和内联汇编代码如下: 方程式: X=40+5 Y=3*12 ---> X=45 Y=36 测试 if x < y - print x+y else print x-y
我正在编写一个程序,其中的要求如下: 有一个名为 Name 的字符串变量,该变量设置为您的全名,包括空格。 只清除 AL 寄存器,不清除 EAX 寄存器的其余部分。 遍历 Name 变量中的每个字符。
我有一个任务,描述如下: - Reads printable characters (20h-7Fh) from the keyboard without echoing - Uppercase le
我正在查看 switch 语句的汇编语言代码。 我了解代码的工作原理以及情况。我的问题是如何决定案例名称? 下面是汇编语言代码,下面是我的解释。我基本上只需要使用跳转表并填写案例名称。 1 8
我是汇编语言新手,我想到了这个问题:构建代码、宏或过程哪个是更好的解决方案?虽然宏中包含的代码只是复制到所需的部分,并且允许执行代码而无需昂贵的跳转,但它确实添加了必须在程序执行时加载的额外指令。此外
我是一名优秀的程序员,十分优秀!