首页 > 解决方案 > x86 函数在 C 中返回 char*

问题描述

我想在 x86 中编写一个函数,该函数将从 C 程序中调用。
该函数应如下所示:

char *remnth(char *s, int n);

我希望它从字符串 s 中删除每个第 n 个字母并返回该字符串。这是我的 remnth.s 文件:

section.text
global remnth

remnth:
; prolog
    push ebp
    mov ebp, esp

; procedure
    mov eax, [ebp+8]; Text in which I'm removing every nth letter
    mov ebx, [ebp+12]; = n
    mov ecx, [ebp+8] ; pointer to next letter (replacement)


lopext:
    mov edi, [ebp+12]     ; edi = n  //setting counter
    dec edi               ; edi--  //we don't go form 'n' to '1' but from 'n-1' to '0'
lop1:
    mov cl, [ecx]         ; letter which will be a replacement
    mov byte [eax], cl    ; replace
    test cl,cl            ; was the replacement equal to 0?
    je exit               ; if yes that means the function is over
    inc eax               ; else increment pointer to letter which will be replaced
    inc ecx               ; increment pointer to letter which is a replacement
    dec edi               ; is it already nth number?
    jne lop1              ; if not then repeat the loop
    inc ecx               ; else skip that letter by proceeding to the next one
    jmp lopext            ; we need to set counter (edi) once more 

exit:
; epilog

    pop ebp     
    ret   

问题是,当我main()在 CI 中调用此函数时,会出现分段错误(核心转储)

据我所知,这与指针高度相关,在这种情况下,我正在返回*char,并且由于我已经看到一些返回的函数int并且它们工作得很好,我怀疑我忘记了*char正确返回 a 的重要内容。

这是我的 C 文件的样子:

#include <stdio.h>

extern char *remnth(char *s,int n);

int main()
{
    char txt[] = "some example text\0";

    printf("orginal = %s\n",txt);
    printf("after = %s\n",remnth(txt,3));

    return 0;
}

任何帮助将不胜感激。

标签: cassemblyx86nasminline-assembly

解决方案


ecx用作指针和cl工作寄存器。由于cl是 的低 8 位ecx,因此您正在使用mov cl, [ecx]指令破坏指针。您需要更改其中一个。通常,// al/ax用于临时工作寄存器,因为对累加器的某些访问使用较短的指令序列。如果您用作工作寄存器,您将希望避免用作指针并改用不同的寄存器(请记住在必要时保留其内容)。eaxraxaleax


推荐阅读