如何使用内联汇编将字符串复制到另一个字符串?

时间:2017-06-26 18:11:11

标签: gcc x86 inline-assembly att

这个简单的代码应该复制字符串“d”中的字符串“c”,只将第一个字符更改为“x”:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char c[5] = "abcd", d[5];

    __asm__(
        "leal %1, %%ebx\n"
        "leal %0, %%ecx\n"

        "movb $'x', (%%ecx)\n"
        "movb 1(%%ebx), %%al\n"
        "movb %%al, 1(%%ecx)\n"
        "movb 2(%%ebx), %%al\n"
        "movb %%al, 2(%%ecx)\n"
        "movb 3(%%ebx), %%al\n"
        "movb %%al, 3(%%ecx)\n"
        "movb $0, 4(%%ecx)\n"

        :"=m"(c)
        :"m"(d)
        :"%ebx", "%ecx", "%eax"
    );

    printf("%s\n", d);
    return 0;
}

但它给出了分段错误错误。我相信我的问题在于约束,但我无法弄清楚如何解决这个问题。

什么是正确的方法,如何更改此代码?

1 个答案:

答案 0 :(得分:0)

首先,当我使用gcc构建并在我的Windows PC上执行时,您的字符串复制代码不会导致异常。但是,字符串副本没有发生,因为您的代码似乎假设寄存器ecx指向变量d,当它实际指向变量c时。下面的代码将变量c的字符串内容复制到d,然后用x替换数组d中的第一个字符。尝试使用gcc进行编译。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char c[5] = "abcd", d[5];

    __asm__(
        "leal %1, %%ebx\n"
        "leal %0, %%ecx\n"

        "movb (%%ecx), %%al\n"
        "movb %%al, (%%ebx)\n"
        "movb 1(%%ecx), %%al\n"
        "movb %%al, 1(%%ebx)\n"
        "movb 2(%%ecx), %%al\n"
        "movb %%al, 2(%%ebx)\n"
        "movb 3(%%ecx), %%al\n"
        "movb %%al, 3(%%ebx)\n"
        "movb 4(%%ecx), %%al\n"
        "movb %%al, 4(%%ebx)\n"
        "movb $'x', (%%ebx)\n"

        :"=m"(c)
        :"m"(d)
        :"%ebx", "%ecx", "%eax"
    );

    printf("String d is: %s\n", d);
    printf("String c remains: %s\n", c);
    return 0;
}  

在Windows PC上使用MinGW gcc编译器时,会产生以下输出:

> gcc testAsm.c
> .\a.exe
String d is: xbcd
String c remains: abcd