如何正确ASM文件链接到C ++? [英] how do i properly link asm files to c++?

查看:447
本文介绍了如何正确ASM文件链接到C ++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个硬件问题,我已经做了所有的编码,但有使用Visual Studio 2010的窗户IM连接与C ASM麻烦++,即时通讯,我把源文件中的主,我的ASM文件中的资源文件,当我尝试编译它只是给了我一个链接错误

  1 GT; ------启动生成:项目:clearArray,配置:调试的Win32 ------
1> clearArray.cpp
1> clearArray.obj:错误LNK2019:​​在函数_main引用解析的外部符号_clearPointerOp
1> clearArray.obj:错误LNK2019:​​在函数_main引用解析的外部符号_clearIndexOp
1> C:\\用户\\陈乔恩\\文档\\ Visual Studio 2010的\\项目\\ clearArray \\调试\\ clearArray.exe:致命错误LNK1120:2无法解析的外部
==========生成:0成功,1失败,0了最新,0已跳过==========

这汉王的目标是用指数法和指针方法清除数组,然后优化生成的ASM code

请帮助!

我的继承人codeS:
的main.cpp

 使用未优化code。与指数和指针//清楚数组
#包括LT&;&iostream的GT;
#包括LT&;&的fstream GT;
#包括timer.h使用命名空间std;为externC{无效clearIndexOp(INT A [],INT大小);}
为externC{无效clearPointerOp为(int * A,INT大小);}const int的大小= 100000;
INT A [大小] = {0};无效clearIndex(INT A [],INT大小)
{
    的for(int i = 0; I<大小;我++)
        A [i] = 0;
}无效clearPointer为(int * A,INT大小)
{
    INT * P;
    为(P =安培; A [0]; P<&安培; A【尺寸】; p ++)
        * p值= 0;
}诠释的main()
{
    双timeIndex = 0;
    双timeIndexOp = 0;
    双timePointer = 0;
    双timePointerOp = 0;
    秒表计时;
    MYFILE ofstream的;
    myfile.open(RESULTS.TXT);    对于(INT N = 2000; N< 1000000; N = N * 2)
    {
        //把值放入数组
        的for(int i = 0; I<大小;我++)
            A [i] = I +兰特()%10 + 1;        time.startTimer();
        clearIndex(A,大小);
        time.stopTimer();
        timeIndex = time.getElapsedTime();        //把值放入数组
        的for(int i = 0; I<大小;我++)
            A [i] = I +兰特()%10 + 1;        time.startTimer();
        clearPointer(A,大小);
        time.stopTimer();
        timePointer = time.getElapsedTime();        //把值放入数组
        的for(int i = 0; I<大小;我++)
            A [i] = I +兰特()%10 + 1;        time.startTimer();
        clearIndexOp(A,大小);
        time.stopTimer();
        timeIndexOp = time.getElapsedTime();        //把值放入数组
        的for(int i = 0; I<大小;我++)
            A [i] = I +兰特()%10 + 1;        time.startTimer();
        clearPointerOp(A,大小);
        time.stopTimer();
        timePointerOp = time.getElapsedTime();        MYFILE<< N现在是:<< N'LT;< \\ n;
        MYFILE<< timeIndex是:<< timeIndex<< \\ n;
        MYFILE<< timePointer是:<< timePointer<< \\ n;
        MYFILE<< timeIndexOp是:<< timeIndexOp<< \\ n;
        MYFILE<< timePointerOp是:<< timePointerOp<< \\ n;
    }
    myfile.close();
}

clearIndexOp.asm

  .386
.MODEL平
.STACK
。code全球_clearIndexOp PROC
_i $ = -8;大小= 4
_A $ = 8;大小= 4
_size $ = 12;大小= 4; {
    推EBP
    MOV EBP,ESP
    子ESP,204; 000000ccH
    推EBX
    推ESI
    推EDI
    LEA EDI,DWORD PTR [EBP-204]
    MOV ECX,51; 00000033H
    MOV EAX,-858993460; ccccccccH
    代表STOSD;的for(int i = 0; I<大小;我++)
;初始化变量
    MOV EAX,0;初始化i = 0到eax中
    MOV EBX,DWORD PTR _size $ [EBP];大小存放在EBX比内存访问速度更快
    MOV ECX,DWORD PTR _A $ [EBP];获得阵列的基础地址
    JMP SHORT $ @ LN3 clearIndex;跳入循环
$ @ LN2 clearIndex:
    添加EAX,1;增加EAX因为EAX = I
$ @ LN3 clearIndex:
    CMP EAX,EBX;检查I<尺寸
    JGE SHORT $ @ LN4 clearIndex;如果退出I> =大小; A [i] = 0;
    MOV DWORD PTR [ECX + EAX * 4],0; A [i] = 0
    JMP SHORT $ @ LN2 clearIndex;回到体循环; C $ CS删除无用/重复$之后
;我们这个缩水code 10的指令只有5指令$ @ LN4 clearIndex:; }
    流行EDI
    流行ESI
    流行EBX
    MOV ESP,EBP
    流行EBP
    RET 0
_clearIndexOp ENDP

clearPointerOp.asm

  .386
.MODEL平
.STACK
。code全球_clearPointerOp PROC
_p $ = -8;大小= 4
_A $ = 8;大小= 4
_size $ = 12;大小= 4; {
    推EBP
    MOV EBP,ESP
    子ESP,204; 000000ccH
    推EBX
    推ESI
    推EDI
    LEA EDI,DWORD PTR [EBP-204]
    MOV ECX,51; 00000033H
    MOV EAX,-858993460; ccccccccH
    代表STOSD; INT * P;
;为(P =安培; A [0]; P<&安培; A [尺寸],P
;初始化变量
    MOV EAX,DWORD PTR _A $ [EBP];数组的基地址
    MOV DWORD PTR _p $ [EBP],EAX; INIT P = A [0]
    MOV EBX,DWORD PTR _p $ [EBP];移动p来EBX
    MOV ECX,DWORD PTR _size $ [EBP];大小存储在ECX从寄存器的访问速度更快
    LEA EDX,DWORD PTR [ECX + EAX * 4]。数组的最后一个索引,A [大小1]
    JMP SHORT $ @ LN3 CLEARPOINT;跳入循环
$ @ LN2 CLEARPOINT:
    添加EAX,4;既然是指针,我们增加EAX 4移动到下一个元素
$ @ LN3 CLEARPOINT:
    CMP EBX,EDX;检查P<尺寸
    宰SHORT $ @ LN4 CLEARPOINT;如果退出P> =大小; * p值= 0;
    MOV DWORD PTR [EBX] 0
    JMP SHORT $ @ LN2 CLEARPOINT; C $ CS删除无用/重复$之后
;我们这个缩水code 11的指令只有5指令$ @ LN4 CLEARPOINT:; }
    流行EDI
    流行ESI
    流行EBX
    MOV ESP,EBP
    流行EBP
    RET 0
_clearPointerOp ENDP


解决方案

问题是你的ASM不被视为一个源文件。

要解决:

1),右键单击您的项目,然后选择Build自定义,然后选中旁边MASM复选框

2)右键单击文件.ASM,选择属性,然后更改项目类型以Microsoft宏汇编。

编辑#2:我现在看到你使用VS所产生的ASM code的修改版本,它几乎没关系

单从PROC声明中删除全局,然后添加结束了ASM文件的末尾。

这应该得到的ASM正确组装和纽带。但它看起来就像你可能在clearPointerOp乱七八糟的东西了,因为它进入在最后一个无限循环。您应该能够从那里弄清楚一旦你的code是编译和链接。

this is a hw problem, ive done all the coding but im having trouble linking the asm with c++, im using windows visual studio 2010, i put the main in source files, and my asm files in the resources files, when i try to compiling it just gives me a linking error

1>------ Build started: Project: clearArray, Configuration: Debug Win32 ------ 
1>clearArray.cpp 
1>clearArray.obj : error LNK2019: unresolved external symbol _clearPointerOp referenced in function _main 
1>clearArray.obj : error LNK2019: unresolved external symbol _clearIndexOp referenced in function _main 
1>C:\Users\Joe Chen\documents\visual studio 2010\Projects\clearArray\Debug\clearArray.exe : fatal error LNK1120: 2 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

the objective of this hw was to clear an array using index method and pointer method, then optimize the generated asm code

please help!!!

heres my codes: main.cpp

// clear array using unoptimized code with index and pointers
#include<iostream>
#include<fstream>
#include"timer.h"

using namespace std;

extern "C" {void clearIndexOp(int A[], int size);}
extern "C" {void clearPointerOp(int *A, int size);}

const int size = 100000;
int A[size] = {0};

void clearIndex(int A[], int size)
{
    for(int i=0; i<size; i++)
        A[i]=0;
}

void clearPointer(int *A, int size)
{
    int *p;
    for(p=&A[0]; p<&A[size]; p++)
        *p=0;
}

int main()
{   
    double timeIndex = 0;
    double timeIndexOp = 0;
    double timePointer = 0;
    double timePointerOp = 0;
    StopWatch time;
    ofstream myfile;
    myfile.open("results.txt");

    for(int n=2000; n<1000000; n=n*2)
    {
        // put values into the array
        for(int i=0; i<size; i++)
            A[i]=i+rand()%10+1;

        time.startTimer();
        clearIndex(A, size);
        time.stopTimer();
        timeIndex =  time.getElapsedTime();

        // put values into the array
        for(int i=0; i<size; i++)
            A[i]=i+rand()%10+1;

        time.startTimer();
        clearPointer(A, size);
        time.stopTimer();
        timePointer = time.getElapsedTime();

        // put values into the array
        for(int i=0; i<size; i++)
            A[i]=i+rand()%10+1;

        time.startTimer();
        clearIndexOp(A, size);
        time.stopTimer();
        timeIndexOp =  time.getElapsedTime();

        // put values into the array
        for(int i=0; i<size; i++)
            A[i]=i+rand()%10+1;

        time.startTimer();
        clearPointerOp(A, size);
        time.stopTimer();
        timePointerOp = time.getElapsedTime();

        myfile << "n is now: " << n << "\n";
        myfile << "timeIndex is: " << timeIndex << "\n";
        myfile << "timePointer is: " << timePointer << "\n";
        myfile << "timeIndexOp is: " << timeIndexOp << "\n";
        myfile << "timePointerOp is: " << timePointerOp << "\n";        
    }
    myfile.close();
}

clearIndexOp.asm

.386
.model flat
.stack
.code

global _clearIndexOp proc
_i$ = -8                            ; size = 4
_A$ = 8                                 ; size = 4
_size$ = 12                             ; size = 4

; {
    push    ebp
    mov ebp, esp
    sub esp, 204                        ; 000000ccH
    push    ebx
    push    esi
    push    edi
    lea edi, DWORD PTR [ebp-204]
    mov ecx, 51                         ; 00000033H
    mov eax, -858993460                 ; ccccccccH
    rep stosd

; for(int i=0; i<size; i++)
; initialize the variables
    mov eax, 0                          ; init i=0 to eax
    mov ebx, DWORD PTR _size$[ebp]      ; size stored in ebx for faster access than memory
    mov ecx, DWORD PTR _A$[ebp]         ; get base addr of array
    jmp SHORT $LN3@clearIndex           ; jump into the loop
$LN2@clearIndex:
    add eax, 1                          ; increase eax since eax=i
$LN3@clearIndex:
    cmp eax, ebx                        ; check that i < size
    jge SHORT $LN4@clearIndex           ; exits if i >= size

; A[i]=0;
    mov DWORD PTR [ecx+eax*4], 0        ; A[i]=0
    jmp SHORT $LN2@clearIndex           ; go back to loop body

; after removing useless/repetitive codes 
; we shrunk this code from 10 instructions to only 5 instructions

$LN4@clearIndex:

; }
    pop edi
    pop esi
    pop ebx
    mov esp, ebp
    pop ebp
    ret 0
_clearIndexOp ENDP              

clearPointerOp.asm

.386
.model flat
.stack
.code

global _clearPointerOp proc 
_p$ = -8                                    ; size = 4
_A$ = 8                                     ; size = 4
_size$ = 12                                 ; size = 4

; {
    push ebp
    mov ebp, esp
    sub esp, 204                            ; 000000ccH
    push ebx
    push esi
    push edi
    lea edi, DWORD PTR [ebp-204]
    mov ecx, 51                             ; 00000033H
    mov eax, -858993460                     ; ccccccccH
    rep stosd

; int *p;
; for(p=&A[0]; p<&A[size]; p
; initialize the variables
    mov eax, DWORD PTR _A$[ebp]             ; base addr of the array
    mov DWORD PTR _p$[ebp], eax             ; init p = A[0]
    mov ebx, DWORD PTR _p$[ebp]             ; move p to ebx
    mov ecx, DWORD PTR _size$[ebp]          ; size stored in ecx for faster access from register
    lea edx, DWORD PTR [ecx+eax*4]          ; last index of array, A[size-1]
    jmp SHORT $LN3@clearPoint               ; jump into loop
$LN2@clearPoint:
    add eax, 4                              ; since it is pointer we increase eax by 4 to move to next element
$LN3@clearPoint:
    cmp ebx, edx                            ; check that p < size
    jae SHORT $LN4@clearPoint               ; exit if p >= size

; *p=0;
    mov DWORD PTR [ebx], 0
    jmp SHORT $LN2@clearPoint

; after removing useless/repetitive codes
; we shrunk this code from 11 instructions to only 5 instructions

$LN4@clearPoint:

; }
    pop edi
    pop esi
    pop ebx
    mov esp, ebp
    pop ebp
    ret 0
_clearPointerOp ENDP            

解决方案

The problem is your asm is not being treated as a source file.

To fix:

1) Right-click your project and choose Build Customizations, then check the box next to masm

2) Right-click your .asm files, choose Properties, then change the Item Type to Microsoft Macro Assembler.

Edit #2: I see now that you're using a modified version of the asm code generated by VS and it's almost okay.

Just remove "global" from the PROC declarations, and then add an END to the end of the asm files.

That should get the asm to assemble and link correctly. But it looks like you probably messed something up in clearPointerOp because it goes into an infinite loop at the end. You should be able to figure it out from there once your code is compiling and linking.

这篇关于如何正确ASM文件链接到C ++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆