源码:
#include
#include
#if 0
void *memcpy_asm(void *dst, const void *src, size_t size)
{
/*movs:把指针DS:SI所指向的数据传送给指针ES:DI所指向的内存单元*/
asm volatile(
"shr $2, %2\n\t"
"cld\n\t"
"rep; movsl\n\t"
"mov %3, %%ecx\n\t"
"and $3, %%ecx\n\t"
"rep; movsb\n\t"
/*输出参数*/
:
/*输入参数:DS段(S:ESI) ES段(D:EDI) c:ecx m:内存变量*/
:"D"(dst),"S"(src),"c"(size), "m"(size)
/*cc:使用的指令会改变CPU的条件寄存器*/
:"memory","cc");
return dst;
}
#endif
void *memcpy_asm(void *dst, const void *src, size_t n)
{
int d0=0, d1=0, d2=0;
asm volatile(
"shr $2, %0 \n\t"
"rep ; movsl \n\t"
"movl %4,%%ecx \n\t"
"andl $3,%%ecx \n\t"
"jz 1f \n\t"
"rep ; movsb \n\t"
"1:"
/*分别表示第零个操作数(%0)–到第二个(%2)操作数*/
: "=&c"(d0),"=&D"(d1),"=&S"(d2)
/*分别表示第三个操作数(%3)到第六个操作数(%6);其中%3个=第%0个;%5==%1;%6==%2*/
: "0"(n),"g"(n),"1"((long)dst),"2"((long)src)
:"memory");
return dst;
}
void *memset_asm(void *dst, char c, size_t size)
{
asm volatile(
"cld\n\t"
"rep; stosb\n\t"
::"a"(c),"D"(dst),"c"(size)
:"memory","cc");
return dst;
}
int memcmp_asm(void *dest, const void *src, size_t size)
{
register int result = 0;
asm volatile(
"cld \n\t"
"repe cmpsb \n\t"
"je 1f \n\t"
"sbb %0,%0 \n\t"
"or $1,%0 \n\t"
"1:"
:"=&a"(result)
:"0"(result),"S"(dest),"D"(src), "c"(size), "m"(size)
:"cc"); //clobber list 告诉gcc在这段内联汇编中哪些寄存器被显式/隐式修改
return result;
}
int main(int argc, char *argv[])
{
char s1[20] = {"1122334455667788"};
char s2[20] = {"11223344AABBCCDD"};
char str[100] = {0};
//memset_asm(s, 'A', strlen(s));
memcpy_asm(str, s1, strlen(s1));
printf("s=%s str = %s\n",s1, str);
printf("s1=s1=%d s2>s1=%d s1
gcc gccinline.c -o gccinline
执行结果:
./gccinline
s=1122334455667788 str = 1122334455667788
s1=s1=0 s2>s1=1 s1
汇编:gcc -S -O gccinline.c
cat gccinline.s
.file "gccinline.c"
.text
.globl memcpy_asm
.type memcpy_asm, @function
memcpy_asm:
.LFB47:
.cfi_startproc
movq %rdi, %rax
movq %rdx, %rcx
#APP
# 26 "gccinline.c" 1
shr $2, %ecx
rep ; movsl
movl %rdx,%ecx
andl $3,%ecx
jz 1f
rep ; movsb
1:
# 0 "" 2
#NO_APP
ret
.cfi_endproc
.LFE47:
.size memcpy_asm, .-memcpy_asm
.globl memset_asm
.type memset_asm, @function
memset_asm:
.LFB48:
.cfi_startproc
movl %esi, %eax
movq %rdx, %rcx
#APP
# 45 "gccinline.c" 1
cld
rep; stosb# 0 "" 2
#NO_APP
movq %rdi, %rax
ret
.cfi_endproc
.LFE48:
.size memset_asm, .-memset_asm
.globl memcmp_asm
.type memcmp_asm, @function
memcmp_asm:
.LFB49:
.cfi_startproc
movq %rdi, %r8
movq %rsi, %rdi
movq %rdx, %rcx
movq %rdx, -8(%rsp)
movl $0, %eax
movq %r8, %rsi
#APP
# 56 "gccinline.c" 1
cld
repe cmpsb
je 1f
sbb %eax,%eax
or $1,%eax
1:
# 0 "" 2
#NO_APP
ret
.cfi_endproc
.LFE49:
.size memcmp_asm, .-memcmp_asm
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "s=%s str = %s\n"
.LC1:
.string "s1=s1=%d s2>s1=%d s1.text
.globl main
.type main, @function
main:
.LFB50:
.cfi_startproc
pushq %r12
.cfi_def_cfa_offset 16
.cfi_offset 12, -16
pushq %rbp
.cfi_def_cfa_offset 24
.cfi_offset 6, -24
pushq %rbx
.cfi_def_cfa_offset 32
.cfi_offset 3, -32
subq $176, %rsp
.cfi_def_cfa_offset 208
movq %fs:40, %rax
movq %rax, 168(%rsp)
xorl %eax, %eax
movabsq $3761687883739705649, %rax
movq %rax, (%rsp)
movabsq $4051048575092012341, %rsi
movq %rsi, 8(%rsp)
movl $0, 16(%rsp)
movq %rax, 32(%rsp)
movabsq $4919130649148932417, %rax
movq %rax, 40(%rsp)
movl $0, 48(%rsp)
leaq 64(%rsp), %rdi
movl $12, %ecx
movl $0, %eax
rep stosq
movl $0, (%rdi)
movq $-1, %rcx
movq %rsp, %rdi
repnz scasb
notq %rcx
leaq -1(%rcx), %rdx
movq %rsp, %rsi
leaq 64(%rsp), %rdi
call memcpy_asm
leaq 64(%rsp), %rcx
movq %rsp, %rdx
movl $.LC0, %esi
movl $1, %edi
movl $0, %eax
call __printf_chk
movl $9, %edx
leaq 32(%rsp), %rsi
movq %rsp, %rdi
call memcmp_asm
movl %eax, %r12d
movl $9, %edx
movq %rsp, %rsi
leaq 32(%rsp), %rdi
call memcmp_asm
movl %eax, %ebp
movl $9, %edx
movq %rsp, %rsi
movq %rsp, %rdi
call memcmp_asm
movl %r12d, %r8d
movl %ebp, %ecx
movl %eax, %edx
movl $.LC1, %esi
movl $1, %edi
movl $0, %eax
call __printf_chk
movq 168(%rsp), %rdx
xorq %fs:40, %rdx
je .L5
call __stack_chk_fail
.L5:
movl $0, %eax
addq $176, %rsp
.cfi_def_cfa_offset 32
popq %rbx
.cfi_def_cfa_offset 24
popq %rbp
.cfi_def_cfa_offset 16
popq %r12
.cfi_def_cfa_offset 8
ret
.cfi_endproc
.LFE50:
.size main, .-main
.ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609"
.section .note.GNU-stack,"",@progbits