c++ - 我如何正确地将 asm 文件链接到 C++?

标签 c++ visual-studio-2010 assembly linker

这是一个硬件问题,我已经完成了所有编码,但我无法将 asm 与 C++ 链接,我使用的是 Windows Visual Studio 2010,我将主要文件放在源文件中,将我的 asm 文件放在资源文件中,当我尝试编译它只会给我一个链接错误

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 ==========

这个hw的目标是使用索引方法和指针方法清除一个数组,然后优化生成的asm代码

请帮忙!!!

这是我的代码: 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            

最佳答案

问题是您的 asm 没有被视为源文件。

修复:

1) 右键单击​​您的项目并选择 Build Customizations,然后选中 masm 旁边的复选框

2) 右键单击​​您的 .asm 文件,选择属性,然后将项目类型更改为 Microsoft Macro Assembler。

编辑 #2:我现在看到您使用的是 VS 生成的 asm 代码的修改版本,它几乎没问题。

只需从 PROC 声明中删除“global”,然后在 asm 文件的末尾添加一个 END。

这应该让 asm 正确地组装和链接。但看起来你可能在 clearPointerOp 中搞砸了一些东西,因为它最后进入了无限循环。一旦您的代码正在编译和链接,您应该能够从那里弄清楚。

关于c++ - 我如何正确地将 asm 文件链接到 C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8162336/

相关文章:

assembly - 访问参数时内联汇编过程崩溃

c++ - Travis-CI Complex Makefile 失败

c++ - 按值删除 map 元素

C++/boost : Writing a more powerful sscanf replacement

c++ - 继承自QLabel的类,为什么不调用自定义槽?

visual-studio-2010 - 关闭后的 Visual Studio 2010 (devenv) 挂起进程

c# - 如何在 Visual Studio 2010 中添加 DirectX 引用

c++ - 使用 JsonCpp 和 Boost 的链接问题

assembly - 在 x86 软件中断期间,具体何时进行上下文切换?

xcode - 如何在 XCode/clang 中为 iPhone 编译独立的 ARM 程序集文件