Trying to figure out the syntax of MASM

I have done some assembly programming on Linux and now I am trying to do this on Windows using MASM. However, I am facing several problems.

(Here I am trying to implement the strlen () function. I know the functional logic / instructions are not optimal, but I'm just trying to pick up something dirty so I can continue 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 look like my jmp shortcuts, throwing unmatched macro folding, etc. What is the correct way to do this? postscript I try to avoid using MASM macros where possible, preferring to type instructions myself.

Can someone please compile this program? Once I see it done right, I'll be on my fun-filled path, I can. Yes, I have looked for resources and still since this question came up.

+3


source to share


2 answers


Can anyone compile this program?

Voilà (explanation in 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

a pointer to a string is required... You have to create a function to convert EAX

to string.

+2


source


This is a macro solution. The length of the string is finally stored in EAX.

The first macro checks an integer DWORD from memory and is faster than regular read and check. Good for big strings.

;//-----------------------------------------------------------------------
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

      

Short version with check:



;//-----------------------------------------------------------------------
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

      

Basically proc:

.data

        anyString byte "Hello World", 0

    .code
        main PROC

        strlenShort OFFSET anyString        ;// => result in EAX

        strlenFast OFFSET anyString     ;// => result in EAX

      

0


source







All Articles