2014-09-11 7 views
3

Я сделал некоторое сборочное программирование в Linux, и теперь я пытаюсь сделать это в Windows с помощью MASM. Тем не менее, я сталкиваюсь с несколькими проблемами.Попытка выяснить синтаксис MASM

(Здесь я пытаюсь реализовать функцию 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, где это возможно, предпочитая самостоятельно кодировать инструкции.

Может кто-то прокомментировать эту программу? Как только я увижу, как это будет сделано правильно, я буду на моем веселом пути, я смогу. Да, я искал ресурсы и все еще, так как этот вопрос встал.

+2

Я думаю, что "повторить" может быть плохим выбором. Я думаю, что это ключевое слово MASM для управления повторением макросов. –

+0

@ Харри, прежде чем я буду делать свой эксперимент, попробуйте это: измените слово 'repeat:' на что-то вроде 'George:' или некоторые из них. Слово 'Repeat' имеет конкретное значение для части макроса MASM –

+0

@IraBaxter, пожалуйста, выключите свой модем для чтения! –

ответ

2

Может кто-то попросит эту программу скомпилировать?

Вуаля (пояснения в комментариях):

.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 в строку.

0

Это решение с макросами. Длина строки окончательно сохраняется в 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 EAX 
Смежные вопросы