I've done some assembly programming on Linux and am now trying to do it on Windows using MASM. I am running into a couple issues though.
(Here I am trying to implement the strlen() function. I know the function logic/instructions aren't optimal, but I'm just trying to rig something dirty up so I can get going on implementing other C library functions.)
.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
When I try to compile, it doesn't appear to like my jmp labels, throwing unmatched macro nesting, etc. Whats the proper way to do this? p.s. I am trying to avoid using MASM macros where possible, preferring to code the instructions myself.
Can someone please make this program compile? Once I see how it is done correctly I will be on my merry way, I will be able to. Yes I looked for resources and still am as this question is up.
Can someone please make this program compile?
Voilà (explanation in the comments):
.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
I suspect you want to output the result of my_strlen. This is not possible with StdOut
because StdOut
needs a pointer to a string. You have to create a function to convert EAX
to a string.