asm( "assembly code" );
asm ("movl $1, %eax\n\tmovl $0, %ebx\n\tint $0x80");
asm ( "movl $1, %eax\n\t"
"movl $0, %ebx\n\t"
"int $0x80");
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int result;
result = a * b;
asm ("nop");
printf ("The result is %d\n", result);
return (0);
}
.file "asm.c"
.section .rodata
.LC0:
.string "The result is %d\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $32, %esp
movl $10, 28(%esp)
movl $20, 24(%esp)
movl 28(%esp), %eax
imull 24(%esp), %eax
movl %eax, 20(%esp)
#APP
# 9 "asm.c" 1
nop
# 0 "" 2
#NO_APP
movl $.LC0, %eax
movl 20(%esp), %edx
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
#include <stdio.h>
int a = 10;
int b = 20;
int result;
int main()
{
asm ( "pusha\\n\\t"
"movl a, %eax\\n\\t"
"movl b, %ebx\\n\\t"
"imull %ebx, %eax\\n\\t"
"movl %eax, result\\n\\t"
"popa");
printf ("the answer is $d\\n", result);
return (0);
}
.file "global.c"
.globl a
.data
.align 4
.type a, @object
.size a, 4
a:
.long 10
.globl b
.align 4
.type b, @object
.size b, 4
b:
.long 20
.comm result,4,4
.section .rodata
.LC0:
.string "the answer is $d\\n"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $16, %esp
#APP
# 9 "global.c" 1
pusha
movl a, %eax
movl b, %ebx
imull %ebx, %eax
movl %eax, result
popa
# 0 "" 2
#NO_APP
movl result, %edx
movl $.LC0, %eax
movl %edx, 4(%esp)
movl %eax, (%esp)
call printf
movl $0, %eax
leave
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
.section .note.GNU-stack,"",@progbits
asm volatitle ("assembly code");
__asm__ ( "pusha\\n\\t"
"movl a, %eax\\n\\t"
"movl b, %ebx\\n\\t"
"imull %ebx, %eax\\n\\t"
"movl %eax, result\\n\\t"
"popa");
asm ("汇编代码" : 输出位置 : 输入操作数 : 改动的寄存器
"constraint" (variable)
约束符号 | 描述 |
a | 使用%eax, %ax 或者 %al 寄存器 |
b | 使用%ebx, %bx 或者 %bl 寄存器 |
c | 使用%ecx, %cx 或者 %cl 寄存器 |
d | 使用%edx, %dx 或者 %dl 寄存器 |
S | 使用%esi或者%si寄存器 |
D | 使用%edi或者%di寄存器 |
r | 使用任何可用的通用寄存器 |
q | 使用%eax, %ebx, %ecx或者%edx中的其一 |
A | 对于64位值使用%eax和%edx寄存器 |
f | 使用浮点寄存器 |
t | 使用第一个(顶部的)浮点寄存器 |
u | 使用第二个浮点寄存器 |
m | 使用变量的内存位置 |
o | 使用偏移内存位置 |
V | 只使用直接内存位置 |
i | 使用立即整数值 |
n | 使用值已知的立即整数值 |
g | 使用任何可用的寄存器或者内存位置 |
I | 使用常数0~31 |
J | 使用常数0~63 |
K | 使用常数0~255 |
L | 使用常数0~65535 |
M | 使用常数0~3 |
N | 使用1字节常数(0~255) |
O | 使用常数0~31 |
cc | 如果汇编代码会改变条件码寄存器,则最好添加此项(在第三个冒号后的那一栏,并不是对所有CPU有效) |
memory | 用在损坏部分中,表示内存被修改了 |
输出修饰符 | 描述 |
+ | 可以读取和写入操作数 |
= | 只能写入操作数 |
% | 如果必要,操作数可以和下一个操作数切换 |
& | 确保输入和输出分配到不同的寄存器中 |
asm ("assembly code" : "=a"(result) : "d"(data1), "c"(data2));
#include <stdio.h>
int main()
{
int data1 = 10;
int data2 = 20;
int result;
asm ( "imull %%edx, %%ecx\\n\\t"
"movl %%ecx, %%eax"
: "=a"(result)
: "d"(data1), "c"(data2));
printf ("The result is %d\\n", result);
return (0);
}
movl $10, 28(%esp)
movl $20, 24(%esp)
movl 28(%esp), %eax
movl 24(%esp), %ecx
movl %eax, %edx
#APP
# 9 "reg.c" 1
imull %edx, %ecx
movl %ecx, %eax
# 0 "" 2
#NO_APP
movl %eax, 20(%esp)
#include <stdio.h>
int main()
{
char input[30] = {"This is a test message.\\n"};
char output[30];
int length = 25;
asm volatile ( "cld\\n\\t"
"rep movsb"
:
: "S"(input), "D"(output), "c"(length));
printf ("%s", output);
return (0);
}
asm ("assembly code"
: "=r"(result)
: "r"(data1), "r"(data2));
#include <stdio.h>
int main()
{
int data1 = 10;
int data2 = 20;
int result;
asm ( "imull %1, %2\\n\\t"
"movl %2, %0"
: "=r"(result)
: "r"(data1), "r"(data2));
printf ("The result is %d\\n", result);
return (0);
}
movl $10, 28(%esp)
movl $20, 24(%esp)
movl 28(%esp), %eax
movl 24(%esp), %edx
#APP
# 9 "regtest2.c" 1
imull %eax, %edx
movl %edx, %eax
# 0 "" 2
#NO_APP
asm ("imull %1, %0"
: "=r"(data2)
: "r"(data1), "0"(data2));
#include <stdio.h>
int main()
{
int data1 = 10;
int data2 = 20;
asm ( "imull %1, %0"
: "=r"(data2)
: "r"(data1), "0"(data2));
printf ("The result is %d\\n", data2);
return (0);
}
%[name]约束条件(variable)
#include <stdio.h>
int main()
{
int data1 = 10;
int data2 = 20;
asm ( "imull %[value1], %[value2]"
: [value2] "=r"(data2)
: [value1] "r"(data1), "0"(data2));
printf ("The result is %d\\n", data2);
return (0);
}
#include <stdio.h>
int main()
{
int data1 = 10;
int result = 20;
asm ( "addl %1, %0"
: "=d"(result)
: "c"(data1), "0"(result)
: "%ecx", "edx");
printf ("The result is %d\\n", result);
return (0);
}
$ gcc -g badreg.c -o badreg
badreg.c: In function ‘main’:
badreg.c:8: error: can't find a register in class ‘DREG’ while reloading ‘asm’
badreg.c:8: error: ‘asm’ operand has impossible constraints
#include <stdio.h>
int main()
{
int data1 = 10;
int result = 20;
asm ( "movl %1, %%eax\\n\\t"
"addl %%eax, %0"
: "=d"(result)
: "c"(data1), "0"(result)
: "%eax");
printf ("The result is %d\\n", result);
return (0);
}
movl $10, 28(%esp)
movl $20, 24(%esp)
movl 28(%esp), %ecx
movl 24(%esp), %eax
movl %eax, %edx
#APP
# 8 "okreg.c" 1
movl %ecx, %eax
addl %eax, %edx
# 0 "" 2
#NO_APP
#include <stdio.h>
int main()
{
int dividend = 20;
int divisor = 5;
int result;
asm ( "divb %2\\n\\t"
"movl %%eax, %0"
: "=m"(result)
: "a"(dividend), "m"(divisor));
printf ("The result is %d\\n", result);
return (0);
}
movl $20, 28(%esp)
movl $5, 24(%esp)
movl 28(%esp), %eax
#APP
# 9 "mem.c" 1
divb 24(%esp)
movl %eax, 20(%esp)
# 0 "" 2
#NO_APP
#include <stdio.h>
void xchange (int src, int des)
{
__asm__ ("xchgb %b0, %b1"
:"=b" (des), "=a"(src)
:"a" (src), "b" (des)
:"memory");
printf ("src is : 0x%x\\n", src);
printf ("des is : 0x%x\\n", des);
}
int main(void)
{
int src = 0x12345678;
int des = 0x87654321;
xchange (src, des);
return (0);
}
[beyes@SLinux assembly]$ ./xchg
src is : 0x12345621
des is : 0x87654378
Error: suffix or operands invalid for `xchg'
__asm__ ("xchgb %b0, %1"
:"=q" (des)
:"m" (src), "0" (des)
:"memory");
[beyes@SLinux assembly]$ gcc xchg.c -o xchg
xchg.c: Assembler messages:
xchg.c:5: Warning: using `%al' instead of `%eax' due to `b' suffix
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |