我已经在Linux上做了一些汇编编程,现在正在尝试使用MASM在Windows上进行汇编编程。不过,我遇到了一些问题。
(在这里,我试图实现strlen()函数。我知道函数逻辑/指令并不是最优的,但我只是试着安装一些脏东西,以便继续实现其他C库函数。)
.386
.model flat, stdcall
option casemap:none
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
.data
testString db "test string", 0 ; 0 -> terminator
.code
my_strlen proc
mov ebp, esp ; function prologue
push esp
push ebx
push ecx
xor ecx, ecx ; set count to 0
mov bl, byte ptr [ebp + 8] ; set low of b to 1st character
repeat:
cmp bl, 0 ; if null terminator, return
jz done
inc ecx ; increase count
mov bl, byte ptr [ebp + 8 + ecx] ; increase *ebx
jmp repeat ; repeat
done:
mov eax, ecx ; return count
pop ecx ; function epilogue
pop ebx
pop esp
ret
my_strlen endp
main:
push offset testString ; result = my_strlen(testString)
call my_strlen
push eax ; StdOut(result)
call StdOut
push 0 ; ExitProcess(0)
call ExitProcess
end main当我试图编译时,它似乎不喜欢我的jmp标签,抛出不匹配的宏嵌套等等。附注:我尽量避免在可能的情况下使用MASM宏,更倾向于自己编写指令。
请有人把这个程序编译一下好吗?一旦我看到它是如何正确的,我将在我的快乐的道路上,我将能够做到。是的,我在寻找资源,现在仍然是这样,因为这个问题已经解决了。
发布于 2014-09-11 21:23:12
请有人把这个程序编译一下好吗?
(评论中的解释):
.386
.model flat, stdcall
option casemap:none
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
.data
testString db "test string", 0
.code
my_strlen proc
; mov ebp, esp ; function prologue
; push esp
push ebp ; this is a correct prologue
mov ebp, esp
push ebx
push ecx
push esi
mov esi, [ebp+8] ; in [EBP+8] is a pointer
xor ecx, ecx
mov bl, byte ptr [esi]
repea: ; "repeat" is a keyword
cmp bl, 0
jz done
inc ecx
mov bl, byte ptr [esi + ecx] ; increase *esi
jmp repea ; repeat
done:
mov eax, ecx
pop esi
pop ecx
pop ebx
leave ; this is a correct epilogue
ret
my_strlen endp
main proc ; this is better
push offset testString
call my_strlen
; push eax ; StdOut(result)
push offset testString ; The MASM32-function StdOut needs only an ASCIZ-string
call StdOut
push 0
call ExitProcess
main endp
end main我怀疑您希望输出my_strlen的结果。这在StdOut中是不可能的,因为StdOut需要一个指向字符串的指针。您必须创建一个函数来将EAX转换为字符串。
发布于 2014-09-13 10:50:37
这是一个使用宏的解决方案。字符串的长度最终存储在EAX中。
首先,宏从内存中检查整个DWORD,并且比按字节读取和检查更快。对更大的弦很好。
;//-----------------------------------------------------------------------
strlenFast MACRO stringPtr:REQ
;//-----------------------------------------------------------------------
local STRLEN_LOOP
mov eax, stringPtr
mov esi, 0
STRLEN_LOOP:
mov ebx, [eax+esi]
mov ecx, ebx
inc esi
and ebx, 0FFh
jz EOS
mov ebx, ecx
inc esi
and ebx, 0FF00h
jz EOS
mov ebx, ecx
inc esi
and ebx, 0FF0000h
jz EOS
mov ebx, ecx
inc esi
and ebx, 0FF000000h
jnz short STRLEN_LOOP
EOS:
dec esi
mov eax, esi
ENDM一种简短的解决方案,并采用逐行检查:
;//-----------------------------------------------------------------------
strlenShort MACRO stringPtr:REQ
;//-----------------------------------------------------------------------
local STRLEN_LOOP
mov eax, stringPtr
mov esi, -1
STRLEN_LOOP:
inc esi
mov ebx, [eax+esi]
and ebx, 0FFh
jnz STRLEN_LOOP
mov eax, esi
ENDM在主要程序中:
.data
anyString byte "Hello World", 0
.code
main PROC
strlenShort OFFSET anyString ;// => result in EAX
strlenFast OFFSET anyString ;// => result in EAXhttps://stackoverflow.com/questions/25796257
复制相似问题