我正在完成一个汇编程序,用一个给定的替换字符替换字符串中的字符。汇编代码调用C函数,汇编程序本身在我的.c文件中从main调用。但是,我试图找到一个适当的寄存器来存储某种计数器来计算一个字符被替换的次数。最终我会在返回调用c函数之前将该值放入eax(在这种情况下会将该值返回给r)。
编辑:修复!我意识到我不需要实际存储我在ebx寄存器中通过程序集调用的c函数的返回值。这释放bl用作计数器,然后我将al分配给bl。由于al是16位版本的eax,我可以返回eax,它将包含更改的字符数!
我的[修复]汇编代码是:
; File: strrepl.asm
; Implements a C function with the prototype:
;
; int strrepl(char *str, int c, int (* isinsubset) (int c) ) ;
;
;
; Result: chars in string are replaced with the replacement character and string is returned.
SECTION .text
global strrepl
_strrepl: nop
strrepl:
push ebp ; set up stack frame
mov ebp, esp
push esi ; save registers
push ebx
xor eax, eax
mov ecx, [ebp + 8] ;load string (char array) into ecx
jecxz end ;jump if [ecx] is zero
mov al, [ebp + 12] ;move the replacement character into esi
mov edx, [ebp + 16] ;move function pointer into edx
xor bl, bl
firstLoop:
xor eax, eax
mov edi, [ecx]
cmp edi, 0
jz end
mov edi, ecx ; save array
movzx eax, byte [ecx] ;load single byte into eax
push eax ; parameter for (*isinsubset)
mov edx, [ebp + 16]
call edx ; execute (*isinsubset)
mov ecx, edi ; restore array
cmp eax, 0
jne secondLoop
add esp, 4 ; "pop off" the parameter
add ecx, 1
jmp firstLoop
secondLoop:
mov eax, [ebp+12]
mov [ecx], al
inc bl
mov edx, [ebp+16]
add esp, 4
add ecx, 1
jmp firstLoop
end:
xor eax, eax
mov al, bl
pop ebx ; restore registers
pop esi
mov esp, ebp ; take down stack frame
pop ebp
ret
答案 0 :(得分:1)
这里还有一些问题: -
确保您没有损坏需要保留的寄存器!在Win32上,必须保留以下内容:edi,esi,ebp和ebx(您正在废弃edi)。其他操作系统可能需要保留不同的寄存器。
您调用的函数也是如此,因此您调用的函数必须保留这些寄存器,但可以自由更改其余的寄存器。
您正在对字符串的结尾进行双字检查,应该是字节检查。
寄存器用法 - 每个寄存器都有一个定义的使用模式,一些指令使用隐式寄存器(例如loop,mul等)
您的评论错误。返回是替换字符的数量,而不是输入字符串,除非代码错误且注释正确。
以下是我如何实现这一点,用VS2010编写并使用MS特定的内联汇编格式: -
int __declspec (naked) my_strrepl (char *string, int c, int (*isinsubset) (int c))
{
__asm
{
push ebp
mov ebp, esp
push esi
push ebx
xor ebx,ebx
mov esi,string
or esi,esi
jz null_string
check_loop:
lodsb
and eax,0xff
jz null_string
push eax
mov edx,isinsubset
call edx
add sp,4
or eax,eax
jz check_loop
inc ebx
mov eax,c
mov [esi-1],al
jmp check_loop
null_string:
mov eax,ebx
pop ebx
pop esi
mov esp,ebp
pop ebp
ret
}
}