2016-10-26 3 views
-1

Я новичок в языке ассемблера, и у меня есть этот код, который, вероятно, изменит длину строки, теперь я знаю, что я близок, но программа продолжает рушиться на меня по любой причине. Проблема в STRREV PROC. Что я делаю неправильно в этом коде?String Reverse in Язык ассемблера x86

INCLUDE Irvine32.inc 
.data 
    prompt BYTE "Enter String: ", 0 
    response BYTE 50 DUP(0) 
    message BYTE " Message entered. ",0 
.code 

swap MACRO a,b 

    xor a,b 
    xor b,a 
    xor a,b 

endM 

STRQRY PROC 
    push ebp 
    mov ebp, esp 
    push edx 
    push ecx 

    mov edx, [ebp+8] 
    call writestring 

    mov ecx, SIZEOF response 
    mov edx, OFFSET response 
    call readstring 


    pop ecx 
    pop edx 
    pop ebp 
    ret 4 

STRQRY ENDP 

STRLEN PROC 
      push ebp 
      mov ebp, esp 
      push ebx 
      push ecx 

      mov edx,[ebp+16] 

      mov eax, 0 


counter: 
      mov cl,[edx+eax] 

      cmp cl, 0  

      JE done 

      inc eax 

      jmp counter 

done: 
      pop ecx 
      pop ebx 
      pop ebp 
      ret 4 

STRLEN ENDP 

STRREV proc 
    push ebp 
    mov ebp, esp 

    push OFFSET response 
    call STRLEN 

    mov edx, [ebp+8] 
    mov esi, 0 
    dec eax 

reverseloop: 

    mov ah, [edx+esi] 
    mov al, [edx+eax] 

    swap ah, al 

    mov [edx+esi],ah 
    mov [edx+eax],al 

    inc esi 
    dec eax 

    cmp esi, eax 
    jb reverseloop 
    ja finish 

finish: 
    pop ebp 
    ret 4 

STRREV endp 

main PROC 

    push OFFSET prompt 
    call STRQRY 

    call writedec 

    mov edx,OFFSET message 
    call WriteString 

    push eax 
    call STRREV 

    mov edx, OFFSET response 
    call WriteString 

    exit 
main ENDP 
END main 
+0

Почему вы «mov edx, [ebp + 16]' в STRLEN? –

+1

Это первый аргумент +8, и он ошибочно добавляет еще один +8 для 2x 'push' после' mov ebp, esp', не понимая, что 'push' влияет только на esp, а не на' ebp' (значения этих двух push-инструкции находятся в '[esp + 0]' == '[ebp-8]' и '[esp + 4]' == '[ebp-4]' ... поэтому он выполняет '[ebp + 16]' вместо '[esp + 16]' или '[ebp + 8]'. ... Во всяком случае, он даже не потрудился отлаживать его, или он пропустил тот факт, что код 'strlen' загружает неправильный адрес строки при этом Точнее, я уже видел этот источник на SO, мне интересно, как им удается каждый раз генерировать одну и ту же ошибку. – Ped7g

+1

Но в этом коде больше ошибок. Продолжайте отладку (вы, вероятно, заметите через некоторое время, что регистрирует 'eax' и' al' делят некоторые биты, а также 'ah' делает и т. д.), – Ped7g

ответ

1

Основная проблема в вашей функции - изменение регистра AL и AH, а затем использование EAX в качестве указателя.
Я решил написать новую функцию на основе вашего кода, внимательно прочитал ее и отлаживал ваш код с помощью правильного эмулятора.

STRREV proc 

;opening the function 
push ebp 
mov ebp, esp 

push OFFSET response 
call STRLEN 

mov edx, [ebp+8] ;edx = offset string to reverse 
mov esi, 0 
dec eax  

mov ebx,edx  ;ebx stores the pointer to the first character 
add ebx,eax`  ;now ebx store the pointer to the last character before the '$' 

reverseloop: 


mov ah, [edx] ;ah stores the value at string[loop count] 
mov al, [ebx] ;al stores the value at string[len-loop count-1] 

;"swap ah,al" is logiclly unnecessary 
;better solution: 

mov [ebx],ah  ; string[loop count] = string[len-loop count-1] 
mov [edx],al  ; string[len-loop count-1] = string[loop count] 

inc edx   ;increment of the right-most pointer 
dec ebx   ;decrement of the right-most pointer 

cmp ebx, eax  ;compares the left-most pointer to the right-most 
jb reverseloop 
jmp finish  ;"ja", there is no need to check a condition twice 

finish: 
pop ebp 
ret 4 

STRREV endp