【发布时间】:2019-05-04 00:37:47
【问题描述】:
我正在尝试将这个 Memmove C 代码组装起来,但没有得到预期的结果。
我在 xubuntu 上使用 x86-64 程序集,调试了 2 小时后,我看不出我哪里错了。
C memmove 代码:
#include <stdio.h>
extern void * memmove(void *dest, void *src, size_t n);
int main () {
char str1[] = "Geeks"; // Array of size 6
char str2[] = "Quiz"; // Array of size 5
puts("str1 before memmove ");
puts(str1);
/* Copies contents of str2 to sr1 */
memmove(str1, str2, sizeof(str2));
puts("\nstr1 after memmove ");
puts(str1);
return 0;
}
/*
void * memmove(void *dest, void *src, size_t n) {
char *d = (char *) dest;
char *s = (char *) src;
if(s == d)
return dest;
if(s < d) {
//copy from back
s=s+n-1;
d=d+n-1;
while(n--) {
*d-- = *s--;
}
}
else {
//copy from front
while(n--)
*d++ = *s++;
}
return dest;
} */
汇编代码:
.globl memmove
# RDI = dest
# RSI = src
# RDX = n
# R8 = d
# R9 = s
memmove:
mov %rdi, %r8 # d = dest
mov %rsi, %r9 # s = src
jmp if_equal
if_equal:
cmp %r8, %r9 # s == d
jz retDest
ja else # s > d
jb if_s_minor # s < d
if_s_minor:
add %rdx, %r9 # s = s + n
sub $1, %r9 # s = s - 1
add %rdx, %r8 # d = d + n
sub $1, %r8 # d = d - 1
jmp while1
while1:
cmp $0, %rdx # n > 0 ?
jna retDest # if n <= 0 go to retDest
sub $1, %rdx # n--
movb (%rsi), %cl # *dst-- = *src--
movb %cl, (%rdi)
leaq -1(%r8), %r8 # *d--
leaq -1(%r9), %r9 # *s--
jmp while1
else:
jmp while2
while2:
cmp $0, %rdx # n > 0 ?
jna retDest
sub $1, %rdx # n--
movb (%rsi), %cl # *dst = *src
movb %cl, (%rdi)
leaq 1(%r8), %r8 # *d++
leaq 1(%r9), %r9 # *s++
jmp while2
retDest:
mov %rdi, %rax
ret
.end
本应在第二张打印件上显示“测验”,但它显示如下:
str1 在 memmove 之前 极客
在 memmove 之后的 str1 极客
【问题讨论】:
-
char str1[] = "Geeks"; // Array of size 100- 不。 && 我不知道memove()是什么。你的意思是memmove()? -
是的,大小为 100 的数组是错误的。我放错了评论。是的,我是 memmove(),我改变了它,因为我以前在同一个文件上有一个 memmove 函数。
-
已编辑帖子
-
你在乎这里的效率吗?一次复制 1 个字节与使用
movups一次复制 16 个字节相比非常慢。 (x86-64 保证 SSE2 可用)。或者更好的 AVX,或者rep movsb如果 AVX 不可用。看看 glibc 的 memcpy 实现就是一个很好的例子。 code.woboq.org/userspace/glibc/sysdeps/x86_64/multiarch/…(glibc memcpy 只使用 memmove。) -
这是我大学的“家庭作业”,如果可能的话,我应该一直移动 8 个字节,但这并不总是可行的。顺便说一句,那个链接里有很多我不能用的东西。