我正在尝试编写 ac 程序,该程序将调用汇编函数来反转字符串。但是,我很难让汇编代码遍历字符串以找到结束字符“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”后似乎立即失败。
在第 25 行使用中断运行 GDB,同时使用“display/c $edi”显示 edi 寄存器会产生以下输出:
(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 寄存器时,我做错了吗?