If statements in masm: Syntax error in control flow directive - masm

I am trying to use the if macro in MASM, but I keep getting the following error message from the MASM assembler: Syntax error in control flow directive. I'm still not sure what the syntax error is here: what is the correct syntax for if statements in MASM?
.686p
.model flat,stdcall
.stack 2048
.data
X byte 1;
ExitProcess proto, exitcode:dword
.code
start:
.IF(x > 1): ; "syntax error in control-flow directive"
mov ah, x;
.ENDIF
invoke ExitProcess, 0
end start

Remove the colon ":" after ). Also, you define X as a capital letter, but use the lowercase x, this is not valid. Assembly is case sensitive.

Related

Problem trying to run Assembly in Visual Studio

I'm trying to run some assembly code in Visual Studio 2012 and call it in C just for testing purposes. As I have no experience writing assembly code I have no idea what is going wrong, so I would greatly appreciate some help!
I get the following errors trying to compile the code:
Error 5 error MSB3721: The command "ml.exe /c /nologo /Zi /Fo"Debug\callee.obj" /W3 /errorReport:prompt /Tacallee.asm" exited with code 1. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V110\BuildCustomizations\masm.targets 49 5 ProjetoASM
Error 2 error A2206: missing operator in expression C:\Users\Suporte\Desktop\ASM\ProjetoASM\ProjetoASM\callee.asm 18 1 ProjetoASM
Error 3 error A2206: missing operator in expression C:\Users\Suporte\Desktop\ASM\ProjetoASM\ProjetoASM\callee.asm 21 1 ProjetoASM
Error 4 error A2206: missing operator in expression C:\Users\Suporte\Desktop\ASM\ProjetoASM\ProjetoASM\callee.asm 8 1 ProjetoASM
Error 1 error A2022: instruction operands must be the same size C:\Users\Suporte\Desktop\ASM\ProjetoASM\ProjetoASM\callee.asm 15 1 ProjetoASM
And the Assembly code:
PUBLIC hello_from_asm
EXTERN puts:PROC
.model flat
.data
msg db 'Hello, world!',0xa
len equ $ - msg
.code
hello_from_asm PROC
mov edx,len
mov ecx,msg
mov ebx,1
mov eax,4
int 0x80
mov eax,1
int 0x80
hello_from_asm ENDP
END
This was supposed to output a "Hello, world!", so any other ideas that might work are also welcome.
C code for completeness:
#include <stdio.h>
extern void hello_from_asm();
int main(){
printf("Hello from C");
hello_from_asm();
return 0;
}
Those detailed MASM error messages tell it all.
mov ecx,msg
You're required to use MASM style. The above instruction tries to load the first byte of msg in a 32-bit register. That's the "size mismatch" error.
What you need is loading the address of msg in ECX. Use
mov ecx, offset msg
The other errors might be about not recognizing the 0x hexadecimal prefix. Try using the h hexadecimal suffix instead. (0Ah, 80h)
The above is easy enough to change, and your code will assemble fine. However don't run it because the int 80h instruction is a Linux system call that is not going to work on Visual Studio 2012 (Windows).
Example 32 bit Visual Studio | Masm program to print "Hello World". I included the most common directives. "legacy_stdio_definitions.lib" is used for VS2015 and later, since printf and scanf were changed to be inlined with the output of the C compiler. You may not need it for VS2012.
.686p ;enable instructions
.xmm ;enable instructions
.model flat,c ;use C naming convention (stdcall is default)
; include C libraries
includelib msvcrtd
includelib oldnames
includelib legacy_stdio_definitions.lib ;for scanf, printf, ...
.data ;initialized data
pfstr db "Hello world!",0dh,0ah,0
.data? ;uinitialized data
.stack 4096 ;stack (optional, linker will default)
.code ;code
extrn printf:near
public main
main proc
push offset pfstr ; 32-bit mode uses stack args
call printf
add esp,4 ; cdecl is caller-pops
xor eax,eax ; return 0
ret
main endp
end

how to call assembly program inside c program- Visual studio 2010

I need to call inline asm function in my c program "mainFunction.c"
#include<stdio.h>
#include<math.h>
double inline __declspec (naked) __fastcall sqrt14(double n)
{
_asm fld qword ptr [esp+4]
_asm fsqrt
_asm ret 8
}
int main(){
double a=10.5;
double b;
b=sqrt14(a);
return 0;
}
When I compile this program I am getting syntax errors.
error C2143: syntax error : missing ';' before '{'
error C2085: 'sqrt14' : not in formal parameter list
error C2054: expected '(' to follow 'inline'
if I change the file name to "mainFunction.cpp" means the program works fine.
You didn't specify which errors you got, but the function definition seems a little suspicious. See - http://msdn.microsoft.com/en-us/library/h5w10wxs.aspx
The compiler cannot generate an inline function for a function marked with the naked attribute, even if the function is also marked with the __forceinline keyword.
It also doesn't make a lot of sense to try stripping a function that's going to be inlined anyway, inlining already does most of the job for you.

C; Inline assembly syntax mistake "Expected string literal before numerical constant"

When I compile the following example code (these are essentially junk assembly statements with no real purpose) I get the following error;
def-asm-pop.c:13:3: error: expected string literal before numeric
constant
Line 13 is the uncommented "ASM" line;
#define iMOV "mov %eax,%ebx\n\t"
#define iNOP "nop\n\t"
#define iASM __asm__(iMOV iNOP)
#define MOV 0xB8
#define NOP 0x90
#define ASM __asm__(MOV NOP)
int main() {
//iASM; /* This one works when uncommented */
ASM; /* The one causes the error when uncommented */
return 0;
}
There maybe an error in my Hello World style attempt at inline assembly, but that is another stepping stone for me to overcome. At this point in time it seems I can't define a list of opcodes and then define an assembly statement list built from them, in the same way I can by defining the text commands. How can I make ASM work like the iASM statement?
As the error message states, the __asm__ operator wants a string and not a number, and in that string it wants valid assembler.
You are trying to directly write binary opcodes, this has not much to do with assembler.
This might work:
#define MOV ".byte 0xB8\n"
#define NOP ".byte 0x90\n"
The exact syntax is of course dependent on your assembler (and the appropriate machine language is dependent on your target platform). This is not much use for anything other than experimenting; it is not a good way to write code.

Is there a way of generating asm code in a .S file using C macros?

I have to generate redundant asm code which keeps calling different C functions
i am trying to do something like
#define CODE_GEN(func) push a \
call func
pop a
invoking something like
CODE_GEN(foo)
will generate
bash-4.1$ gcc -E mk.S
# 1 "mk.S"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "mk.S"
# 1 "asm_gen.h" 1
# 2 "mk.S" 2
# 13 "mk.S"
pusha call foo popa iret
but this fails in compilation
bash-4.1$ gcc -m32 mk.S
mk.S: Assembler messages:
mk.S:13: Error: junk `foo popa iret' after expression
mk.S:13: Error: suffix or operands invalid for `pusha'
is there a way to delimit asm code written in a single line in a .S file ?
semicolons ';' can be used in place of line breaks.
So something like
#define CODE_GEN(func) push a; \
call func; \
pop a;
will compile and work
Yes, by using semicolons, see the other answer. C macros expand to a single string with no line breaks, but semicolons get around that.
You can also use GNU Assembler macros. This is totally untested, could be wrong:
.macro CODEGEN func
push a
call \func
pop a
.endm

Undefined reference to multiply

I'm trying to call C function in assembler. This is my code:
C:
int multiply(int what)
{
return what * 2;
}
ASM:
extern multiply
start:
mov eax, 10
push eax
call multiply
jmp $
;empty
times 510-($-$$) db 0
dw 0xAA55
I'm compiling C code to elf by gcc (MinGW) and ASM code by NASM. I'm compiling it without any problems, but when I'm trying to use this code(for creating .bin file):
gcc -o test.bin work.o test.o
I' getting this error:
Does anybody know how to call C function from ASM code, compile it and link it to working .bin file? Please help.
Try to add '_' to multiply:
extern _multiply
Works for me in this simple example:
global _main
extern _printf
section .data
text db "291 is the best!", 10, 0
strformat db "%s", 0
section .code
_main
push dword text
push dword strformat
call _printf
add esp, 8
ret
Try "global multiply" instead of "extern multiply" in your .asm file. You shouldn't need the underscore for ELF (I don't think), but you can get Nasm to automagically add an underscore to anything "extern" or "global" by adding "--prefix _" to Nasm's command line.
Edit: I take that back, "extern" is correct. You seem not to have a "main". Try adding "--nostartfiles"
(may be only one hyphen) to gcc's command line.
Best,
Frank

Resources