将指针的值复制到 Assembly 中的另一个新指针

Posted

技术标签:

【中文标题】将指针的值复制到 Assembly 中的另一个新指针【英文标题】:Copying the value of a pointer to another new pointer in Assembly 【发布时间】:2012-10-13 15:10:29 【问题描述】:

更新:我可以在我的代码中使用 strcpy。

我正在尝试在 x86 汇编(att 语法)中编写 strdup 的实现,将 C 中的代码转换为汇编中的代码。

C 代码:

char* func( int x, char* name)

    namestr = (char *) malloc( strlen(name) + 1 );
    strdup( namestr, name );
    free( name ); //Just showing what I plan to do later.

    return namestr;


汇编代码:

;basic start, char* I'm trying to copy is at 12(%ebp)
new_string: 
    pushl   %ebp
    movl    %esp, %ebp
    pushl   %edi
    subl    $20, %esp
    movl    12(%ebp), %ecx
    movl    %ecx, %edi
    movl    (%ecx), %ecx
    movl    %ecx, -8(%ebp)

;get the length of the string + 1, allocate space for it
.STR_ALLOCATE: 
    movl    $0, %eax
    movl    $-1, %ecx
    repnz   scasb
    movl    %ecx, %eax
    notl    %eax
    subl    $1, %eax
    addl    $1, %eax
    movl    %eax, (%esp)
    call    malloc
    movl    %eax, -12(%ebp)

;copy value of of the char* back to %eax, save it to the stack, pass the address back
.STR_DUP: 
    movl    -8(%ebp), %eax
    movl    %eax, -12(%ebp)
    leal    -12(%ebp), %eax

.END:
    popl    %edi
    leave
    ret

当我运行代码时,我只得到了一部分 char*。 示例:传入“Stack Overflow”让我得到“Stac@@#$$”。 我想我在 movl 上做错了什么,不太确定是什么。

p/s:我很确定我的 strlen 有效。

第 2 部分: 我写的代码会将指针传回给调用者吗?就像释放我稍后分配的任何空间的能力一样。

【问题讨论】:

因为你得到了正确的 4 个字符,我怀疑你正在复制一个指针(字)大小的区域而不是整个字符串,即。 e.在某些地方,您正在使指针与数组混淆(除了这在此处比在 C 中更有害)。 我猜你的原型是这样的: mystrcpy(char * src, char** dest) 因为 movl (%ecx),%ecx 因为这与 strcpy 不完全一样,也许你应该先写出 C 代码,然后添加到你的问题中 您不需要为strcpy()strlen() 分配任何内存。在值为 0 的字节之后停止读/写。 @H2CO3 是的,我很确定你是对的,但我自己看不到。 @MarcovandeVoort 我已经在 C 中添加了代码。 【参考方案1】:

如果有一点生疏的汇编技能,它看起来像这样:

    pushl   %ebp
    movl    %esp, %ebp
    pushl   %edi
    pushl   %esi
    subl    $20, %esp
    movl    12(%ebp), %edi
;get the length of the string + 1, allocate space for it
.STR_ALLOCATE: 
; next is dangerous. -1 is like scan "forever". You might want to set a proper upper bound here, like in "n" string variants.
    movl    $-1, %ecx
    repnz   scasb
    notl    %ecx
;    subl    $1, %ecx
;    addl    $1, %ecx
    movl    %ecx, -8(%ebp)
    pushl   %ecx
    call    malloc
    add     $4,%esp
    movl    %eax, -12(%ebp)   
    movl    -8(%ebp),%ecx
    movl    %eax, %edi
    movl    12(%ebp).%esi
    rep     movsb
    movl    -12(%ebp),%eax
    popl    %esi
    popl    %edi
    leave
    ret     

【讨论】:

好吧,代码可以工作,但是如果我在释放新的 char* 后尝试释放原始的 char*,我会收到一个错误,说它已经被释放了。 不调用例程就可以正常释放?尝试在例程之前和之后打印指针值。我不知道你的确切目标和 ABI 是什么,我只是复制了原始的样式,并保存了所有额外的 regs

以上是关于将指针的值复制到 Assembly 中的另一个新指针的主要内容,如果未能解决你的问题,请参考以下文章

将mp3标签的值复制到一批MP3文件的另一个标签

如何获取复制到剪贴板的数据值并将其设置为android studio中的另一个值

从 C++ 中的另一个线程读取指针

如何从从 Assembly 返回到 COBOL 的指针中寻址数据缓冲区

通过传输功能将数据从一个项目复制到 BQ 中的另一个项目是不是需要成本?

将图像的区域复制到另一个图像中的另一个区域