我正在尝试编写一个 c 程序,它将调用一个汇编函数来反转一个字符串。但是,我很难让汇编代码遍历字符串以找到结束字符“0”。
我的C代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// These functions will be implemented in assembly:
//
void strrev(char *str) ;
int main(){
char *str1;
str1 = strdup("Hello World");
strrev(str1);
printf("str1 reversed: \"%s\"\n", str1) ;
free(str1);
return 0;
}
我的任何汇编代码都很简单:
; File: strrev.asm
; A subroutine called from C programs.
; Parameters: string A
; Result: String is reversed and returned.
SECTION .text
global strrev
_strrev: nop
strrev:
push ebp
mov ebp, esp
; registers ebx,esi, and edi must be saved if used
push ebx
push edi
xor esi, esi
xor eax, eax
lea ecx, [esp+8] ; load the start of the array into ecx
jecxz end ; jump if [ecx] is zero
mov edi, ecx
reverseLoop:
cmp byte[edi], 0
je end
inc edi
inc eax
jmp reverseLoop
end:
pop edi ; restore registers
pop ebx
mov esp, ebp ; take down stack frame
pop ebp
ret
我现在想让这段代码做的只是遍历字符串,直到它在 reverseLoop 中找到结尾。但是,如果我尝试使用 gdb 并单步执行程序,它似乎在查看第一个字符“H”后立即失败。
在使用“display/c $edi”显示 edi 寄存器时使用 GDB 在第 25 行中断运行产生以下输出:
(gdb)
reverseLoop () at strrev.asm:25
25 cmp byte[edi], 0
1: /c $edi = 72 'H'
这是对的,但如果我向下一步到 inc edi,edi 立即变得不正确。它应该是“E”,因为“Hello World”中的第二个字符是“e”。但是,gdb 输出将其列为“I”:
27 inc edi
1: /c $edi = 72 'H'
(gdb)
28 inc eax
1: /c $edi = 73 'I'
我在遍历 edi 寄存器时是否做错了什么?
最佳答案
您将 edi
寄存器的内容打印为一个字符,但内容实际上是一个地址。您真正想要的是显示 edi
中的地址指向什么。
也许试试
display *((char *) $edi)
关于在 C 中调用汇编函数,反转字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16398208/