x86 函数在 C 中返回 char*
x86 function returning char* in C
我想在 x86 中编写一个函数,它将被 C 程序调用。
该函数应如下所示:
char *remnth(char *s, int n);
我希望它从字符串 s 和 return 该字符串中删除第 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
问题是,当我在 C 中从 main()
调用此函数时,出现分段错误(核心已转储)
据我所知,这与指针高度相关,在这种情况下,我 returning *char
,因为我已经看到一些函数 returns int
而且他们工作得很好,我怀疑我忘记了一些重要的事情 returning a *char
正确。
这是我的 C 文件的样子:
#include <stdio.h>
extern char *remnth(char *s,int n);
int main()
{
char txt[] = "some example text[=12=]";
printf("orginal = %s\n",txt);
printf("after = %s\n",remnth(txt,3));
return 0;
}
我们将不胜感激。
您正在使用 ecx
作为指针,使用 cl
作为工作寄存器。由于 cl
是 ecx
的低 8 位,您正在使用 mov cl, [ecx]
指令破坏您的指针。你需要改变一个或另一个。通常,al
/ax
/eax
/rax
用于临时工作寄存器,因为某些对累加器的访问使用较短的指令序列。如果您使用 al
作为工作寄存器,您将希望避免使用 eax
作为指针,而是使用不同的寄存器(记住在必要时保留其内容)。
您需要在 return 之前将 return 值加载到 eax 中。我假设你想要 return 一个指向字符串开头的指针,所以那将是 [ebp+8]
.
我想在 x86 中编写一个函数,它将被 C 程序调用。
该函数应如下所示:
char *remnth(char *s, int n);
我希望它从字符串 s 和 return 该字符串中删除第 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
问题是,当我在 C 中从 main()
调用此函数时,出现分段错误(核心已转储)
据我所知,这与指针高度相关,在这种情况下,我 returning *char
,因为我已经看到一些函数 returns int
而且他们工作得很好,我怀疑我忘记了一些重要的事情 returning a *char
正确。
这是我的 C 文件的样子:
#include <stdio.h>
extern char *remnth(char *s,int n);
int main()
{
char txt[] = "some example text[=12=]";
printf("orginal = %s\n",txt);
printf("after = %s\n",remnth(txt,3));
return 0;
}
我们将不胜感激。
您正在使用 ecx
作为指针,使用 cl
作为工作寄存器。由于 cl
是 ecx
的低 8 位,您正在使用 mov cl, [ecx]
指令破坏您的指针。你需要改变一个或另一个。通常,al
/ax
/eax
/rax
用于临时工作寄存器,因为某些对累加器的访问使用较短的指令序列。如果您使用 al
作为工作寄存器,您将希望避免使用 eax
作为指针,而是使用不同的寄存器(记住在必要时保留其内容)。
您需要在 return 之前将 return 值加载到 eax 中。我假设你想要 return 一个指向字符串开头的指针,所以那将是 [ebp+8]
.