[segment .data use32]
; ******************************************************************
str: resb 50
str1: resb 50
str2: resb 50
aTmpWord: dw 0
aTmpDWord: dd 0
strlen:
push EBP
mov EBP, ESP
mov AL, 0h
mov EDI, dword [EBP + 8]
mov EBX, 0
vypocet_str:
cld
repne scasb
je koniec_str
inc EBX
mov EDI, [EDI + EBX]
jmp vypocet_str
koniec_str:
mov EAX, EBX
mov ESP, EBP
pop EBP
ret
;************
prologue
push dword [str]
call strlen
call WriteNewLine
call WriteInt32
epilogue
答案 0 :(得分:1)
您的代码中存在多个错误
1)strlen
正式宣布为size_t strlen(const char *s);
。参数是指向字符串的指针。使用push dword [str]
,您不会传递指针,而是传递字符串的前4个字节。将其更改为push str
。 NASM(与MASM不同)然后计算str
的地址。
2)cdecl
调用约定确定参数在堆栈上传递,调用者必须清除堆栈。你正确推动了争论,但没有清除堆栈。在add esp, 4
之后添加call strlen
。
3)repne
需要初始化ECX
。这是重复的最大计数。
4)repne
是循环的指令。您不需要额外的循环(jmp vypocet_str
)。当ECX> 0时,它重复以下指令,并且指令不会告诉"等于" (零标志设置)。因此,ECX可用于确定重新运行的计数 - 稍作调整。
TL; DR:这是你的美丽作业:
%include 'rw32.inc' ; http://www.fit.vutbr.cz/~iklubal/IAS/
[segment .data use32]
str: db "hello world", 0
[segment .code use32]
strlen:
push ebp
mov ebp, esp
mov al, 0
mov edi, dword [EBP + 8]
mov ecx, -1
repne scasb
neg ecx
sub ecx, 2
mov eax, ecx
mov esp, ebp
pop ebp
ret
prologue
push str
call strlen
add esp, 4
call WriteNewLine
call WriteInt32
epilogue