我正在开发一个 C 语言程序,它接受一个字符串并通过调用一个用汇编编写的函数打印出相同的字符串。
我的 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;
}
我的 .asm 文件是:
; 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
mov ecx, [ebp+8] ; load the start of the array into ecx
jecxz end ; jump if [ecx] is zero
;mov edi, ecx
mainLoop:
add eax, 1 ;inc eax would work as well
add ecx, 1
mov dl, [ecx]
cmp dl, 0 ; compare current ecx with 0
je reverseLoop ;if ecx is 0, we are done
jmp mainLoop ;if ecx isnt 0, keep looping
reverseLoop:
mov ecx, [ebp+8] ;reload the start of the arrary into ecx
mov esi, ecx ; esi poinst to start of array
add ecx, eax
mov edi, ecx
dec edi ;edi points to end of array
shr eax, 1 ;eax is the count
jz end ;if string is 0 or 1 chars long, jump to end
reverseLoop_1:
mov cl, [esi] ;load start of array into cl
mov bl, [edi] ;load end of array into bl
mov [esi], bl ;swap
mov [edi], al
inc esi
dec edi
dec eax ;loop
jnz reverseLoop_1
end:
pop edi ;restore registers
pop ebx
mov esp, ebp ;take down stack frame
pop ebp
ret
程序运行成功,但输出为:
str1 reversed: "dlroW "
在第一个单词之后,第二部分“Hello”被打印为字节(5 个方 block ,每个角都有数字)。什么会导致这种情况?
最佳答案
reverseLoop:
mov ecx, [ebp+8] ;reload the start of the arrary into ecx
mov esi, ecx ; esi points to start of array
add ecx, eax ;
mov edi, ecx ;
dec edi ;edi points to end of array
shr eax, 1 ;eax is the count
jz end ;if string is 0 or 1 chars long, jump to end
reverseLoop_1:
mov cl, [esi] ;load start of array into cl
mov bl, [edi] ;load end of array into bl
mov [esi], bl ;swap
mov [edi], al ; AL?!? Should it not be CL?
inc esi ;
dec edi ;
dec eax ;loop
jnz reverseLoop_1
在上面,你读入了 CL,然后存储了 AL。
我会这样做,并且完全不检查 eax:
mov edi, ecx ;
dec edi ;edi points to end of array
reverseLoop_1:
cmp esi, edi ; when esi >= edi we're done.
jae finished ;
mov cl, [esi] ;load start of array into cl
mov bl, [edi] ;load end of array into bl
mov [esi], bl ;swap
mov [edi], cl ;
inc esi ;
dec edi ;
jmp reverseLoop_1
finished:
关于用C调用汇编代码,输出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16412938/