I am trying to run procedure from asm file in cpp file but i get such errors:
Error 1 error LNK2019: unresolved external symbol _calka referenced in function _main D:\Addem\main.obj Project
Error 2 error LNK1120: 1 unresolved externals D:\Addem\Debug\Project.exe 1 1 Project
Here is my main.cpp:
#include <iostream>
using namespace std;
extern "C" void calka();
int main()
{
calka();
system("Pause");
return 0;
}
And my calka.asm
; The calka Subroutine (calka.asm)
public _calka
INCLUDELIB kernel32.lib
INCLUDELIB user32.lib
INCLUDELIB Irvine32.lib
INCLUDE Irvine32.inc
INCLUDE macros.inc
.data
BUFFER_SIZE = 50
buffer BYTE BUFFER_SIZE DUP(?)
filename BYTE 80 DUP(0)
fileHandle HANDLE ?
Rozmiar dw ?
Znak db ?
Suma dw ?
Minus db 0
wynik dw ?
temp dd ?
.code
_calka proc near
; Let user input a filename.
mWrite "Podaj nazwe pliku (z rozszerzeniem): "
mov edx,OFFSET filename
mov ecx,SIZEOF filename
call ReadString
; Open the file for input.
mov edx,OFFSET filename
call OpenInputFile
mov fileHandle,eax
; Check for errors.
cmp eax,INVALID_HANDLE_VALUE ; error opening file?
jne file_ok ; no: skip
mWrite <"Cannot open file",0dh,0ah>
jmp quit ; and quit
file_ok:
; Read the file into a buffer.
mov edx,OFFSET buffer
mov ecx,BUFFER_SIZE
call ReadFromFile
jnc check_buffer_size ; error reading?
mWrite "Error reading file. " ; yes: show error message
call WriteWindowsMsg
jmp close_file
check_buffer_size:
cmp eax,BUFFER_SIZE ; buffer large enough?
jb buf_size_ok ; yes
mWrite <"Error: Buffer too small for the file",0dh,0ah>
jmp quit ; and quit
buf_size_ok:
mov buffer[eax],0 ; insert null terminator
;mWrite "File size: "
;call WriteDec ; display file size
;call Crlf
; Display the buffer.
; Pytanie o wielkosc przedzialu
mWrite "Podaj wielkosc przedzialu h na osi x: "
mov edx,OFFSET Rozmiar
mov ecx,SIZEOF Rozmiar
call ReadDec
mov Rozmiar, ax
;mWrite <"Buffer:",0dh,0ah,0dh,0ah>
;mov edx,OFFSET buffer ; display the buffer
;call WriteString
;call Crlf
mov ecx, 15
mov ebx, OFFSET buffer
mov si, 0
jmp odczyt1
odczyt:
mov ebx, temp
inc ebx
odczyt1:
mov cl, byte ptr [ebx]
mov Znak, cl
mov temp, ebx
cmp Znak, '$' ;koniec pliku
je koniec
cmp Znak, 3bh ;srednik - nastepna liczba
je nastepna
cmp Znak, 20h ;spacja - ponowne wczytanie
je odczyt
cmp Znak, '-'
je Zmien_znak
mov al, Znak
sub al, 30h
mov bl, al
mov bh, 0
mov ax, 10
mul si
add ax, bx
mov si, ax
jmp odczyt
Zmien_znak:
mov Minus, 1
jmp odczyt
nastepna:
cmp Minus, 0
je dodaj
jne odejm
dodaj:
add Suma, si
mov si, 0
jmp odczyt
odejm:
sub Suma, si
mov Minus, 0
mov si, 0
jmp odczyt
koniec:
cmp Minus, 0
je dod
jne minu
dod:
add Suma, si
mov si, 0
jmp kon
minu:
sub Suma, si
mov Minus, 0
mov si, 0
kon:
mov ax, Suma
mul Rozmiar
mWrite "Wynik calkowania: "
cmp ax,0
;mov ebx, eax
jg plus
mWrite "-"
mov bx, 0
sub bx, ax
mov ax, bx
plus:
call WriteDec
close_file:
mov eax,fileHandle
call CloseFile
; Zeby aplikacja sie nie zamknela, heheszki :D
mov edx,OFFSET Rozmiar
mov ecx,SIZEOF Rozmiar
call ReadString
quit:
exit
_calka ENDP
END
I have tried everything what I can focus on - adding obj files to linker and so on. I only want to type the name of file, read date from it and calculate it. Calka.asm works well unless I try to get it work in my cpp file.
What am I doing wrong?
Irvine32.inc
includesSmallWin.inc
and that sets.MODEL flat, stdcall
. So, every procedure will be decorated by default as if the calling convention were STDCALL._calka
becomes_calka@0
. For the CDECL calling convention needed formain.cpp
you have to override the default calling convention for the procedure withPROC C
. Now the underscore will be added automatically. TLDR:calka proc C
.The best is, you create a new project. I'll describe the procedure for Microsoft Visual Studio 2015 RC on Windows 10. The procedure is quite similar for other VS versions.
1) Start Visual Studio 2015 RC and choose
FILE - New - Project
.2) In the next window choose
Win 32 Console Application
.3) You get a confirmation. Click on
Next >
.4) In the next window choose
[X] Console application
[X] Empty project
Click on
Finish
.5) Now choose
PROJECT - Build Customizations...
.6) In the next window tick
masm(.targets,.props)
and click onOK
.7) Create main.cpp:
PROJECT - Add New Item
.8) In the next window choose
C++File(.cpp)
, give it a name and click onAdd
.9) Create calka.asm:
PROJECT - Add New Item
. In the next window chooseC++File(.cpp)
and - IMPORTANT! - give it a name with.asm
extension. Click onAdd
.10) Now check if the
.asm
file has the right properties. In the Solution Explorer right-click on the file and chooseProperties
.11) In the Property Page you should see
Excluded From Build (empty) or No
Item Build Microsoft Macro Assembler
Click on
OK
.12) Now you can fill the files with content.
You don't need
system("Pause")
since CTRL-F5 builds, runs and pauses the application.In the
.asm
file deleteand let Visual Studio them automatically include. Add to
the full path to the files. That's better than to change the settings of VS.
Change
to
13) Build and run with CTRL-F5.
The application will be opened in a new window.