2012-03-21 99 views
0

我得到了这个工作,大家都谢谢!C汇编编程

我有一门功课编写与bigmult.c

C程序应该乘两个无符号的十六进制数一起我的C程序转至汇编程序mulq.s。我已经开始了,但我想我需要很多帮助。这是组装的介绍,所以它不是很长。

以下是完整的问题:

请你写称为 big_mult.c相乘两个无符号整数,x和y,从 在命令行中读取一个C程序。输出是一对无符号整数 ,表示完整的128位乘积x * y的最重要和最不重要的64位。输入和输出将以十六进制格式以 给出。你的C程序将负责读取 输入并打印输出,但它会调用一个函数mull.s来实现 的实际乘法运算。您的C程序应该只使用int或 unsigned int变量,并且不应该执行任何算术运算。由mull.s定义的函数 应在程序main中的 之前的C中具有以下声明。 void mull(unsigned int x,unsigned int y,unsigned int * high,unsigned int * low); 该产品的最低有效64位将被分配到 低位,并且该产品的最高有效64位将被分配为高位 。请记住将适当的标题注释放入您的程序集文件(普通C注释/ * ... * /将适用于 程序集) 。 编写该汇编程序的一种方法是在C中编写一个类似的程序 ,使用-S选项 将其编译为汇编代码,并修改生成的汇编代码以执行所需的操作。您的最终 汇编代码应该很短,并且应该只包含一个 乘法指令。

我开始编写一个虚拟程序,让代码的不重要的部分在顶部,然后我完全失去了做什么。我有pushq指令来推送%rbp并将地址移动到%rsp。在这之后我该怎么做?

任何提示将受到欢迎!

我迄今为止代码:

.section __TEXT,__text,regular,pure_instructions 
    .globl _main 
    .align 4, 0x90 
_main: 
    pushq %rbp 
    movq %rsp, %rbp 

我的C程序:

#include <stdio.h> 
void mull(unsigned int x, unsigned int y, unsigned int* high, unsigned int* low); 
int main(int argc, char* argv[]) { 
    unsigned long long int x, y; 
    if(argc != 3) 
     printf("Usage: bigmult x1 x2 <where x1 and x2 are hexadecimal integers>\n"); 
    else { 
     sscanf(argv[1], "%x", &x); 
     sscanf(argv[2], "%x", &y); 
     printf("%x x %x = ", x, y); 
     mull(x, y, &x, &y); 
    } 
    return 0; 
} 
+0

您是否按照给出的建议尝试过? – 2012-03-21 20:33:43

+6

'编写这个汇编程序的一种方法是在C中编写一个类似的程序,使用-S选项将其编译为汇编代码,并修改生成的汇编代码以执行所需的操作。“这是一个很好的起点。 – 2012-03-21 20:34:43

+1

我可以更直率吗?请**执行建议**。编写一个处理所有事情的C程序,无需任何汇编程序。然后使用由-S生成的输出。你几乎可以得到任何你在'免费'挣扎的东西。 – gbulmer 2012-03-21 20:39:16

回答

2

我很想添加自己的评论,但该#* & $%计算器规则不允许我做评论,直到!我有2800万个信用点(可能少一点)。

首先,你想尽可能简单地用C编写你的mull()函数。如果你使用两个32位整数(可能只是'int',但取决于你的平台),结果代码会更简单(更简单)。如果你这样做,从你的教授的评论来看,这应该归结为一个32位* 32位= 64位乘法的乘法指令。如果你使用64位整数作为你的输入,你的CPU上可能没有64位* 64位= 128位指令,但即使它对于你的任务来说是过度的。如果没有,那么编译器会发出一系列指令来执行64位* 64位= 128位的乘法运算,这使得您很难理解正在发生的事情。

当您将单独的C文件构建到与main()的目标文件链接的目标文件&时,您想要执行的操作是获取其反汇编&寻找multiply指令。一旦找到它,向后追踪以找出它的参数来自哪里......它们可能位于寄存器中,也可能位于堆栈中的内存位置,具体取决于系统的ABI。然后向前追踪,直到函数返回,看看返回给调用者的乘法结果在哪里。

您将需要在mult()的程序集版本中复制该功能,但出现以下异常:C代码编译版本可能包含一些很好的序言和尾声指令,这些指令在函数中不需要这与mult()一样简单。但是除非编译器真的非常擅长优化,否则它不会注意到这一点,编译结果可能只有它真正需要的八倍。从你的教授的评论中,你的整个mult()组装函数甚至可能总共只有2到6条指令......并且取决于你的ABI,你可能甚至可能不需要使用堆栈。 (对于x86,您将会,但对于PowerPC或其他RISC机器,您不需要这么简单的功能,因为对于许多RISC机器,只有几个参数的函数可以将所有参数传递到寄存器中,因此它们不需要。堆栈的话)

因此,假设你需要使用堆栈,你的函数可能看起来是这样的:

_mult: 
    ...instructions to move parameters from stack locations into registers... 
    ...multiply instruction using those registers... 
    ...instructions to move the results into the appropriate stack locations 
     for return values (or return value registers, depending on your ABI)... 
    ...and finally, your processor's "return" instruction 

...共计也许最多6个指令。