#include<stdio.h>
double x = 1.2345678;
double y = 2.3456789;
double z;
double fun(double *a, double *b){
return *a + *b;
}
int main(){
__asm__ (
"movq %1, %%rdi;"
"movq %2, %%rsi;"
"call fun;"
"movq %%xmm0, %0;"
// The arguments of fun are not double but double *and return is double,so the xmm0 is return register.
:"=r"(z)
:"r"(&x),"r"(&y) //address of x and y are reference arguments.
: "rax","rdi","rsi"
);
printf("%lf\n",z);
}
#include<stdio.h>
/*
double fun(double x, double y){
double retur;
__asm__ (
"movsd %1, %%xmm0\n\t"
"movsd %2, %%xmm1\n\t"
"addsd %%xmm1, %%xmm0\n\t"
"movsd %%xmm0, %0\n\t"
:"=m"(retur)
:"m"(x),"m"(y)
:"%xmm0","%xmm1","memory"
);
return retur;
} */
double fun(double x, double y){
double z;
__asm__ (
"movsd %1, %%xmm0\n\t"
"movsd %2, %%xmm1\n\t"
"addsd %%xmm1, %%xmm0\n\t"
"movsd %%xmm0, %0\n\t"
"movq %0, %%rax\n\t"
:"=m"(z)
:"m"(x),"m"(y)
:"%xmm0","%xmm1","memory"
);
}
int main(){
double x =1.11111;
double y =2.22222;
double z=fun(x,y);
printf("%lf\n",z);
return 0;
}
/*
The instruction set "movss or movsd" only move data between xmm and memory,
but cannot between xmm and general purpose register.
so constraint condition must be"
:"m"(x),"m"(y)
:"=m"(retur)
*/
#include<stdio.h>
/* method one.
long long fun(long long a, long long b){
long long result;
__asm__ (
"movq %1, %%rax;"
"movq %2, %%rbx\n\t"
"addq %%rbx, %%rax;"
"movq %%rax, %0\n\t"
: "=r"(result)
: "r"(a), "r"(b)
: "%rax", "%rbx"
);
return result;
} */
// method two.
long long fun(long long a, long long b){
__asm__ (
"movq %1, %%rax;" //both ; and \n\t are Ok for endl.
"movq %2, %%rbx;"
"addq %%rbx, %%rax\n\t"
: "=r"(a) // this line is only for defining constraint condition completely!
: "r"(a), "m"(b)
: "%rax", "%rbx"
);
}
int main(){
long long x = 10343434400L;
long long y = 300454544545L;
long long z = fun(x, y);
printf("%lld\n",z);
return 0;
}
makefile
# 定义编译器和链接器
CXX := g++
CC := gcc
AS := as
LD_GOLD := gold
# 定义编译选项
CXXFLAGS := -Wall -O2
CFLAGS := -Wall -O2
ASFLAGS :=
# 定义链接选项
LDFLAGS :=
# 自动寻找所有的源文件
CPP_SRCS := $(wildcard *.cpp)
C_SRCS := $(wildcard *.c)
S_SRCS := $(wildcard *.s)
# 生成目标文件名
CPP_ELFS := $(patsubst %.cpp,%.elf,$(CPP_SRCS))
C_ELFS := $(patsubst %.c,%.elf,$(C_SRCS))
S_ELFS := $(patsubst %.s,%.elf,$(S_SRCS))
# 默认目标
all: $(CPP_ELFS) $(C_ELFS) $(S_ELFS)
# C++ 文件的编译和链接规则
%.elf: %.cpp
$(CXX) $(CXXFLAGS) $< -c -o $(patsubst %.elf,%.o,$@)
$(CXX) $(patsubst %.elf,%.o,$@) -o $@
# C 文件的编译和链接规则
%.elf: %.c
$(CC) $(CFLAGS) $< -c -o $(patsubst %.elf,%.o,$@)
$(CC) $(patsubst %.elf,%.o,$@) -o $@
# 汇编文件的编译和链接规则,使用gold
%.elf: %.s
$(AS) $(ASFLAGS) $< -o $(patsubst %.elf,%.o,$@)
$(LD_GOLD) $(patsubst %.elf,%.o,$@) -o $@
# 清理构建产物
clean:
rm -f *.o *.elf
.PHONY: all clean