my laptop is mac pro i7
I have assembly course this semester and I have to working on VS2022
so I install windows through bootcamp win10 and install vs2022
when I write any code with .model flat// .386 ...ets it shows syntax error
and when I include address of irvine32.inc library then call foe example call writeString
it is error (undefined symbol)
literally I saw every tutorial about include irvine..setmasm..etc
but it is still errors code
.386
.model flat,stdcall
.stack 4096
INCLUDElib C :\Users\atpc\Downloads\Irvine\Irvine\irvine32.inc
ExitProcess proto, dwExitCode:dword
.data
msg byte "hello world",0
.code
main proc
mov edx,offset msg
call writeString
call ExitProcess,0
main endp
end main
the above code shows theses errors:
Related
I've been using Visual Studio to assemble and link cpp programs that include masm (.asm) files. I want to be able to do this myself, on the command line. I used the ml.exe that Visual Studio provides to assemble my masm code (at Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx86\x86\ml.exe).
However, when I try to compile my project with gcc main.cpp fib.obj -o main, I get an error saying that the .obj architecture does not match the target architecture (i386 architecture of input file 'fib.obj' is incompatible with i386:x86-64 output).
So my question is, simply, how do I compile this project?
What I've Tried
The two things that I've done to get different errors (which I think are more promising) are (1) to utilize the ml64 executable from ...\Hostx86\x64\ml64.exe or ...\Hostx64\x64\ml64.exe, and (2) to use the -m32 option for gcc.
ml64
Using ml64 I have been unable to assemble my masm code. with the following source file, ml64 spits out this response:
; int fib(int);
.386
.model flat, c
.code
fib proc uses ebx ecx, i:dword
mov eax, 0 ; current fib number
mov ebx, 1 ; next fib number
while_1:
cmp i, 0
jle while_1_end
; add eax -> ebx and mov previous ebx into eax
mov ecx, ebx ; store new current fib number
add ebx, eax ; sum previous fib numbers
mov eax, ecx ; set eax to current fib value
dec i
jmp while_1
while_1_end:
; the ith fib number is in eax
ret
fib endp
end
...\fib> ml64 fib.asm
Microsoft (R) Macro Assembler (x64) Version 14.29.30136.0
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: fib.asm
fib.asm(2) : error A2008:syntax error : .
fib.asm(3) : error A2008:syntax error : .
fib.asm(6) : error A2008:syntax error : ebx
fib.asm(24) : fatal error A1010:unmatched block nesting : fib
I presume that .386 isn't right for a x64 target, but removing it changes the error very little (it only removes the syntax error line 2).
I don't really want to use x64 assembly if it isn't the same as x32, but I'll use this solution if it works. I think my second option is more promising.
gcc -m32
I don't believe I can tell gcc to build to a 32-bit target because I don't have 32-bit versions of the libraries. When running gcc -m32 main.cpp fib.obj I get cannot find -lmingw32, cannot find -lgcc, cannot find -lgcc_ex, etc. Should I get these libraries, and if so, where do I find them? It seems a bit awful to download 32-bit libraries on my x64 computer just to assemble masm, and I don't think I should have to, seeing as Visual Studio is able to compile my project simply by setting the target to Win32.
Is there a different way of telling gcc to target 32-bit architecture, or are the libraries perhaps hidden in the Visual Studio files, or something else? I'm pretty sure that if I could get gcc to target x32, it would solve my problem, because Visual Studio targets x32, and when I change the target to x64 I get the same error I have been getting (module machine type 'x86' conflicts with target machine type 'x64').
I'm trying to use MinGW-w64 to compile assembly code on Windows. The test code I am trying to compile is (I'm sure this code extremely bad, but the problem lies in the linker, not the actual code):
.intel_syntax noprefix
.text
.globl _start
_start:
push rbp
mov rbp, rsp
and rsp, -64
sub rsp, 64
mov rax, 0
leave
push 0
call _ExitProcess#4
And the command for I used for compiling is this:
gcc -nostdlib simpletest.s -o out.exe
It doesn't matter to the outcome if I add -kernel32 at the end of the command or not.
No matter what I try I keep getting the following error:
Undefined reference to '_ExitProcess#4'
I should add that the same gcc is perfectly capable of compiling C code to assembly, and then compile that assembly code to an exe.
I have a problem with calling C function from asm project created in visual studio (Win10 x64, Visual Studio 2015). Project consist of one asm file:
.586
.model flat, stdcall
option casemap:none
includelib msvcrt.lib
ExitProcess PROTO return:DWORD
extern printf:near
.data
text BYTE "Text", 0
.code
main PROC
push offset text
call printf
add esp,4
invoke ExitProcess,0
main ENDP
end main
When I build project, linker outputs the error:
Error LNK2019 unresolved external symbol _printf referenced in
function _main#0
Linker output parameters:
/OUT:"C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.exe"
/MANIFEST:NO /NXCOMPAT
/PDB:"C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.pdb"
/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib"
"uuid.lib" "odbc32.lib" "odbccp32.lib" /MACHINE:X86 /SAFESEH:NO
/INCREMENTAL:NO
/PGD:"C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.pgd"
/SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"Debug\SP_Lab7_Demo.exe.intermediate.manifest"
/ERRORREPORT:PROMPT /NOLOGO /TLBID:1
If I comment call print, then everything executes normally (even Windows API function). Is there any way to call C function from asm file without creating cpp file that includes <cstdio>?
Is it possible to do?
Microsoft refactored much of the C runtime and libraries in VS 2015. Some functions are no longer exported from the C library (some are defined in a C header file). Microsoft has some compatibility libraries like legacy_stdio_definitions.lib and legacy_stdio_wide_specifiers.lib, but you can also choose to use the older Visual Studio 2013 platform toolset with the older C libraries.
To change the platform toolset: pull down the Project menu; select Properties...; go to Configuration Properties/General, and change Platform Toolset to Visual Studio 2013 (v120)
It appears that it' possible to use the Visual Studio 2015 Toolset with a few modifications.
You'll need to add these libraries to your dependencies: libcmt.lib, libvcruntime.lib, libucrt.lib, legacy_stdio_definitions.lib. Alternatively you could use includelib to include these libraries in your assembly file.
Specify C calling convention for your main procedure using PROC C
At the end of your file (and this is important) do not use end main, use end only. Not fixing this may cause unexpected crashes.
Although we can use ExitProcess to exit our application, we can also put the return code in EAX and do a ret to return. The C runtime calls our main function, and will call the shutdown code for us upon returning.
The code could look like:
.586
.model flat, stdcall
option casemap:none
includelib libcmt.lib
includelib libvcruntime.lib
includelib libucrt.lib
includelib legacy_stdio_definitions.lib
ExitProcess PROTO return:DWORD
extern printf:NEAR
.data
text BYTE "Text", 0
.code
main PROC C ; Specify "C" calling convention
push offset text
call printf
add esp, 4
; invoke ExitProcess,0 ; Since the C library called main (this function)
; we can set eax to 0 and use ret`to have
; the C runtime close down and return our error
; code instead of invoking ExitProcess
mov eax, 0
ret
main ENDP
end ; Use `end` on a line by itself
; We don't want to use `end main` as that would
; make this function our program entry point
; effectively skipping by the C runtime initialization
You can call C functions, but then you'll need to link with the C library. Exactly how that is done will depend on what C library you want to link with. I'd suggest finding a minimal C runtime, such as the WCRT library.
The library will probably require initialization, and might require you to define a bunch of buffers somewhere for its book keeping.
Instead of going to all this trouble, I'd suggest you just stick to Windows API, and in your case use the WriteConsole function.
I have a problem with calling C function from asm project created in visual studio (Win10 x64, Visual Studio 2015). Project consist of one asm file:
.586
.model flat, stdcall
option casemap:none
includelib msvcrt.lib
ExitProcess PROTO return:DWORD
extern printf:near
.data
text BYTE "Text", 0
.code
main PROC
push offset text
call printf
add esp,4
invoke ExitProcess,0
main ENDP
end main
When I build project, linker outputs the error:
Error LNK2019 unresolved external symbol _printf referenced in
function _main#0
Linker output parameters:
/OUT:"C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.exe"
/MANIFEST:NO /NXCOMPAT
/PDB:"C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.pdb"
/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib"
"comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib"
"uuid.lib" "odbc32.lib" "odbccp32.lib" /MACHINE:X86 /SAFESEH:NO
/INCREMENTAL:NO
/PGD:"C:\Users\apple\Documents\SP_Lab7\Debug\SP_Lab7_Demo.pgd"
/SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"Debug\SP_Lab7_Demo.exe.intermediate.manifest"
/ERRORREPORT:PROMPT /NOLOGO /TLBID:1
If I comment call print, then everything executes normally (even Windows API function). Is there any way to call C function from asm file without creating cpp file that includes <cstdio>?
Is it possible to do?
Microsoft refactored much of the C runtime and libraries in VS 2015. Some functions are no longer exported from the C library (some are defined in a C header file). Microsoft has some compatibility libraries like legacy_stdio_definitions.lib and legacy_stdio_wide_specifiers.lib, but you can also choose to use the older Visual Studio 2013 platform toolset with the older C libraries.
To change the platform toolset: pull down the Project menu; select Properties...; go to Configuration Properties/General, and change Platform Toolset to Visual Studio 2013 (v120)
It appears that it' possible to use the Visual Studio 2015 Toolset with a few modifications.
You'll need to add these libraries to your dependencies: libcmt.lib, libvcruntime.lib, libucrt.lib, legacy_stdio_definitions.lib. Alternatively you could use includelib to include these libraries in your assembly file.
Specify C calling convention for your main procedure using PROC C
At the end of your file (and this is important) do not use end main, use end only. Not fixing this may cause unexpected crashes.
Although we can use ExitProcess to exit our application, we can also put the return code in EAX and do a ret to return. The C runtime calls our main function, and will call the shutdown code for us upon returning.
The code could look like:
.586
.model flat, stdcall
option casemap:none
includelib libcmt.lib
includelib libvcruntime.lib
includelib libucrt.lib
includelib legacy_stdio_definitions.lib
ExitProcess PROTO return:DWORD
extern printf:NEAR
.data
text BYTE "Text", 0
.code
main PROC C ; Specify "C" calling convention
push offset text
call printf
add esp, 4
; invoke ExitProcess,0 ; Since the C library called main (this function)
; we can set eax to 0 and use ret`to have
; the C runtime close down and return our error
; code instead of invoking ExitProcess
mov eax, 0
ret
main ENDP
end ; Use `end` on a line by itself
; We don't want to use `end main` as that would
; make this function our program entry point
; effectively skipping by the C runtime initialization
You can call C functions, but then you'll need to link with the C library. Exactly how that is done will depend on what C library you want to link with. I'd suggest finding a minimal C runtime, such as the WCRT library.
The library will probably require initialization, and might require you to define a bunch of buffers somewhere for its book keeping.
Instead of going to all this trouble, I'd suggest you just stick to Windows API, and in your case use the WriteConsole function.
i'm trying to compile the following code on windows 7 (with NASM):
[BITS 32]
extern ExitProcess
import ExitProcess kernel32.dll
extern MessageBoxA
import MessageBoxA user32.dll
segment .data use32
Caption db 'Caption Text',0
Text db "My MessageBox Text.",0
segment .code use32
..start:
push dword 0
push dword Caption
push dword Text
push dword 0
call [MessageBoxA]
push dword 0
call [ExitProcess]
To compile this, I tried nasm -o test.o test.asm, but then it says:
test.asm:4: error: parser: instruction expected
test.asm:6: error: symbol `import' redefined
test.asm:6: error: parser: instruction expected
Why doesn't it work?
EDIT: ok. simple mistake... nasm -o test.o -f obj test.asm works...
Seems like a known problem. Resolution suggested in http://cboard.cprogramming.com/windows-programming/114989-nasm-import-directive-failing-expected-instruction-error.html
You should not have to use Obj. That is meant for DOS not Windows. Yes, you can use a ton of compiler directives in your ASM code to make it work in Windows, but if you compile with type Win32, you will end up with code specifically that works in Windows. Unfortunately whoever wrote NASM worte it in such a way that import doesn't work in Win32 mode (even though it should, as import is a very standard, and required operation for working in Windows). And even MORE unfortunately is that the person who wrote NASM seems to have stopped adding/improving/upgrading the program and has basically abandoned the project. And with no way for the community to fix this bug our selves (the source code for NASM isn't publicly available), that leaves us with a HUGELY DEFECTIVE PRODUCT!