Search code examples
windowsassemblyx86masm

Trying to figure out MASM syntax


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.


Solution

  • 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.