How can I compile assembly language with gcc and codeblock? - gcc

I am now trying to compile the following codes with gcc and codeblock:
#include <stdio.h>
int main()
{
char alphabet = 'X';
printf ("Type letter = ");
asm{ //line 8
mov ah, 02
mov dl, [alphabet] // line 9
int 21h
}
printf ("\n");
return (0);
}
The error messages I have got are as follows:
error: expected '(' before '{' token line 8
error: 'mov' was not declared in this scope line9
I am compiling for x86 computer, and was wondering how I could compile the above codes successfully. Thanks!

Unfortunately gcc doesn't support simple syntax like this:
asm {
mov ah, 02
mov dl, [alphabet]
int 21h
}
You can find more information on the gcc-inline-assembler with the link DCoder commented: click me
Explaining everything would be too much for an answer, so I simply write the code for gcc, which should do the job for you:
__asm__(
"movb $2, %%ah;"
"movb %0, %%dl;"
"int $0x21;"
:
: "r"(alphabet)
: "%ah", "%dl"
);
Note, that you can also use the keyword asm instead of __asm__.

Related

gcc inline assembly: how to use intel syntax temporarily with constraint 'm' under 'gcc -masm=att' [duplicate]

This question already has answers here:
How to set gcc or clang to use Intel syntax permanently for inline asm() statements?
(2 answers)
Can I use Intel syntax of x86 assembly with GCC?
(2 answers)
Closed last year.
I'd like to use intel syntax gcc inline assembly, leaving gcc's default -masm=att dialect untouched.
The following code works fine:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a = 123;
int b = 0;
printf("before: a = %d\n", a);
printf("before: b = %d\n", b);
__asm__ __volatile__ (
".intel_syntax noprefix\n\t"
"mov eax, %[a]\n\t"
"mov %[b], eax\n\t"
".att_syntax prefix\n\t"
: [b]"+r"(b)
: [a]"r"(a)
: "eax"
);
printf("after: a = %d\n", a);
printf("after: b = %d\n", b);
return 0;
}
// before: a = 123
// before: b = 0
// after: a = 123
// after: b = 123
But if i change Output Operands Constraint from register('r') to memory('m'), error occurs:
Error: junk `(%rbp)' after expression
In the generated assembly file, I find this:
#APP
.intel_syntax noprefix
mov eax, -16(%rbp)
mov -12(%rbp), eax
.att_syntax prefix
#NO_APP
It looks like gcc renders Assembler Template using AT&T Effective-Address dialect.
I searched the web, Extended Asm shows something like "Multiple assembler dialects in asm templates" and "x86 Operand Modifiers", but I still didn't solve the problem.
Is there a way to tell gcc, (maybe some instructions around __asm__, telling gcc to do operand-substitution with Intel-syntax addressing modes temporarily, like -masm=intel do in the whole file), render the Assembler Template using Intel Effective-Address dialect temporarily in __asm__ () block, not the whole file, like this:
#APP
.intel_syntax noprefix
mov eax, [%rbp - 16]
mov [%rbp - 12], eax
.att_syntax prefix
#NO_APP

error: invalid 'asm': operand number missing after %-letter when using inline assembly with GCC

I'm tring to convert a simple assembly code of MS to use with gcc, the MS assembly I try to convert is right below. I have two int variables, number and _return:
mov eax, number
neg eax
return, eax
and, I have tried this:
asm("movl %eax, %0" :: "g" ( number));
asm("neg %eax");
asm("movl %0, %%eax" : "=g" ( return ));
But, the compiler gives me this error:
main.c:17:9: error: invalid 'asm': operand number missing after %-letter
Where is the error, and, how I can fix this error?
Thanks
You can't do it like that because you're overwriting registers without telling the compiler about it. Also, the % is a special character, similar to printf.
It's also better to put all the instructions in one asm or else the compiler might do something unexpected in between.
Try this instead:
asm("movl %%eax, %1\n\t"
"neg %%eax\n\t"
"movl %0, %%eax" : "=g" ( _return ) : "g" ( number) : "eax");
There's probably a better way, though:
asm("neg %0": "=a" ( _return ) : "a" ( number));
I don't know why you can't just do (in C):
_return = -number;
Try something like:
#include <stdio.h>
#include <stdlib.h>
int main(int ac,char**av)
{
int n=ac>1?atoi(av[1]):42;
asm ("movl %0, %%eax \n\t"
"neg %%eax \n\t"
"movl %%eax, %0 \n\t" : "+r" (n)::"eax");
printf("%d\n",n);
}
The issues are:
order of operands is instr src,dst
%% instead of %
no isolated lines of assembler -- the input/output/clobber list is associated to all of the assembler block
'+r' to have a parameter that works as both input & output
I doubt even MS allows using keyword "return" that way
And to make it even more efficient:
asm("neg %0" : "+r" (n) ::); // works as well

GCC inline assembly error: Error: junk `(%esp)' after expression

GCC inline assembly error: Error: junk `(%esp)' after expression
I'm studying gcc inline assembly. My environment is Win 7 32bit, mingw-gcc 4.6.1.
I have got a problem about the 'm' constraint. Here is my c function code:
static int asm_test(int a, int b)
{
int c = 0;
__asm__ __volatile__(".intel_syntax\n"
"mov eax, %1\n" //error
"mov edx, %2\n" //error
"add eax, edx\n"
"mov %0, eax\n" //error
".att_syntax"
:"=m"(c)\
:"m"(a),"m"(b)\
:"eax","edx"
);
return c;
}
For at&t code, it is like this:
static int asm_test(int a, int b)
{
int c = 0;
__asm__ __volatile__(
"movl %1, $eax\n" //error
"movl %2, $edx\n" //error
"addl $edx, $eax\n"
"movl $eax, %0\n" //error
:"=m"(c)\
:"m"(a),"m"(b)\
:"eax","edx"
);
return c;
}
For each of the three lines which operate input/output operands, gcc generate an error when compiling, read like this:
C:\Users\farta\AppData\Local\Temp\cc99HxYj.s:22: Error: junk `(%esp)' after expression
If i use 'r' for input/output constraint, the code will work. But I cannot understand why it works and what the error stands for. Can anyone tell me? As far as I know 'm' is just telling gcc not to allocate registers but directly access them in memory if inline asm code try to access input/output operands. Is this correct?
Thanks a lot.
The problem here is the GCC generates AT&T syntax construct for %0, %1 and %2. If you look at the generated assembly, it looks like:
.intel_syntax
mov eax, 8(%ebp)
mov edx, 12(%ebp)
add eax, edx
mov -4(%ebp), eax
which is not a valid Intel syntax.
Generally, you don't need to include in the inline assembly explicit load/store operation - just specify register constraint and the compiler will generate loads/stores by itself. This has the advantage that even if your variables (parameters, locals) do not reside in memory at all, but are in registers your code will still be correct - unlike in the case if you explicitly put memory load/stores there.
For your example, try the following code, look at the assembly (gcc -S) and notice how the compiler will perform moves from argument area (e.g. stack on x86) all by itself.
int asm_test(int a, int b)
{
__asm__ __volatile__ (
".intel_syntax\n"
"add %0, %1 \n"
".att_syntax \n"
:"+r"(a)
:"r"(b));
return a;
}

How to write multiline inline assembly code in GCC C++?

This does not look too friendly:
__asm("command 1"
"command 2"
"command 3");
Do I really have to put a doublequote around every line?
Also... since multiline string literals do not work in GCC, I could not cheat with that either.
I always find some examples on Internet that the guy manually insert a tab and new-line instead of \t and \n, however it doesn't work for me. Not very sure if your example even compile.. but this is how I do:
asm volatile( // note the backslash line-continuation
"xor %eax,%eax \n\t\
mov $0x7c802446, %ebx \n\t\
mov $1000, %ax \n\t\
push %eax \n\t\
call *%ebx \n\t\
add $4, %esp \n\t\
"
: "=a"(retval) // output in EAX: function return value
:
: "ecx", "edx", "ebx" // tell compiler about clobbers
// Also x87 and XMM regs should be listed.
);
Or put double quotes around each line, instead of using \ line-continuation. C string literals separately only by whitespace (including a newline) are concatenated into one long string literal. (Which is why you need the \n inside it, so it's separate lines when it's seen by the assembler).
This is less ugly and makes it possible to put C comments on each line.
asm volatile(
"xor %eax,%eax \n\t"
"mov $0x7c802446, %ebx \n\t"
"mov $1000, %ax \n\t"
"push %eax \n\t" // function arg
"call *%ebx \n\t"
"add $4, %esp \n\t" // rebalance the stack: necessary for asm statements
: "=a"(retval)
:
: "ecx", "edx", "ebx" // clobbers. Function calls themselves kill EAX,ECX,EDX
// function calls also clobber all x87 and all XMM registers, omitted here
);
C++ multiline string literals
Interesting how this question pointed me to the answer:
main.cpp
#include <cassert>
#include <cinttypes>
int main() {
uint64_t io = 0;
__asm__ (
R"(
incq %0
incq %0
)"
: "+m" (io)
:
:
);
assert(io == 2);
}
Compile and run:
g++ -o main -pedantic -std=c++11 -Wall -Wextra main.cpp
./main
See also: C++ multiline string literal
GCC also adds the same syntax as a C extension, you just have to use -std=gnu99 instead of -std=c99:
main.c
#include <assert.h>
#include <inttypes.h>
int main(void) {
uint64_t io = 0;
__asm__ (
R"(
incq %0
incq %0
)"
: "+m" (io)
:
:
);
assert(io == 2);
}
Compile and run:
gcc -o main -pedantic -std=gnu99 -Wall -Wextra main.c
./main
See also: How to split a string literal across multiple lines in C / Objective-C?
One downside of this method is that I don't see how to add C preprocessor macros in the assembly, since they are not expanded inside of strings, see also: Multi line inline assembly macro with strings
Tested on Ubuntu 16.04, GCC 6.4.0, binutils 2.26.1.
.incbin
This GNU GAS directive is another thing that should be in your radar if you are going to use large chunks of assembly: Embedding resources in executable using GCC
The assembly will be in a separate file, so it is not a direct answer, but it is still worth knowing about.

Error in my first assembly program (GCC Inline Assembly)

After a lot of internet research I implemented a small assembler routine in my C++ program to get the CPU's L1 cache size using cpuid.
int CPUID_getL1CacheSize() {
int l1CacheSize = -1;
asm ( "mov $5, %%eax\n\t" // EAX=80000005h: L1 Cache and TLB Identifiers
"cpuid\n\t"
"mov %%eax, %0" // eax into l1CacheSize
: "=r"(l1CacheSize) // output
: // no input
: "%eax" // clobbered register
);
return l1CacheSize;
}
It works perfectly on Windows 7 64 bit with MinGW (GCC, G++). Next I tried this on my Mac computer using GCC 4.0 and there must be an error somewhere because my program shows strange strings in the ComboBoxes and some signals cannot be connected (Qt GUI).
This is my first assembler program, I hope someone can give me a hint, Thanks!
I think that CPUID actually clobbers EAX, EBX, ECX, EDX, so it's probably just a register trashing problem. The following code appears to work OK with gcc 4.0.1 and 4.2.1 on Mac OS X:
#include <stdio.h>
int CPUID_getL1CacheSize()
{
int l1CacheSize = -1;
asm ( "mov $5, %%eax\n\t" // EAX=80000005h: L1 Cache and TLB Identifiers
"cpuid\n\t"
"mov %%eax, %0" // eax into l1CacheSize
: "=r"(l1CacheSize) // output
: // no input
: "%eax", "%ebx", "%ecx", "%edx" // clobbered registers
);
return l1CacheSize;
}
int main(void)
{
printf("CPUID_getL1CacheSize = %d\n", CPUID_getL1CacheSize());
return 0;
}
Note that you need to compile with -fno-pic as EBX is reserved when PIC is enabled. (Either that or you need to take steps to save and restore EBX).
$ gcc-4.0 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2
CPUID_getL1CacheSize = 64
$ gcc-4.2 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2
CPUID_getL1CacheSize = 64
$
I finally resolved the problem. I got a compiler error while playing around: "error: PIC register '%ebx' clobbered in 'asm'" and after some internet research I modified my code to:
int CPUID_getL1CacheSize() {
int l1CacheSize = -1;
asm volatile ( "mov $5, %%eax\n\t"
"pushl %%ebx; cpuid; popl %%ebx\n\t"
"mov %%eax, %0"
: "=r"(l1CacheSize)
:
: "%eax"
);
return l1CacheSize;
}
Thanks Paul, The compiler option -fno-pic is a nice solution too.
Greetings

Resources