在程序集x86 IRVINE32中查找字符串长度

时间:2016-10-20 21:17:09

标签: assembly x86 irvine32

我是汇编程序设计的新手,我试图弄清楚这个程序的最后一块拼图。当我显示一个字符串(" Hello")时,它显示为0而不是5.为什么会发生这种情况,我需要做些什么来改变它?

TITLE 


INCLUDE Irvine32.inc

.data

prompt       BYTE   "Enter String: ", 0
response     BYTE   50 DUP(0)
message      BYTE   " Message entered. ",0

.code   

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+8]
             call   writedec

             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

main         PROC

             push   OFFSET prompt
             call   STRQRY



             push   eax 
             call   STRLEN

             mov    edx,OFFSET message
             call   WriteString

             mov    edx, OFFSET response
             call   WriteString

             exit
main         ENDP
END          main

1 个答案:

答案 0 :(得分:0)

你说你想找出输入字符串的长度,但这正是IRVINE32 readstring 函数在EAX寄存器中返回的内容!

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

在此块中,ECX应该比您提供的输入缓冲区的大小小1。这允许添加NULL终止符。您将响应定义为50个字节,因此mov ecx, 49就可以了。

call   STRQRY
***HERE EAX HAS THE LENGTH OF THE INPUT!***
push   eax 
call   STRLEN

STRLEN 程序运行时,它需要一个地址作为参数,但是你提供一个长度!这就是崩溃的原因。

 mov    edx, [bp+8]   <<< This needs to be the ADDRESS to start at!
 mov    eax, 0
counter:
 mov    cl,[edx+eax]
 ...
  mov    edx,[ebp+8]
  call   writedec
  mov    eax, 0
 counter:
  mov    cl,[edx+eax]
  cmp    cl, 0      
  JE     done
  inc    eax 
  jmp    counter
 done:

在此代码中,您在错误的位置使用 writedec !此时,EAX与计算的长度不同。将call writedec移到 done 标签下方。

STRLEN 程序中,push / pop EBX寄存器,您应该保存/恢复EDX寄存器。

总之,这就是 STRLEN 程序的样子:

STRLEN       PROC 
    push   ebp 
    mov    ebp, esp
    push   edx
    push   ecx
    mov    edx, [bp+8]
    mov    eax, 0
counter:
    mov    cl, [edx+eax]
    cmp    cl, 0
    JE     done
    inc    eax
    jmp    counter
done:
    call   writedec         <<< Length calculated by you
    pop    ecx
    pop    edx
    pop    ebp
    ret    4
STRLEN       ENDP

以及如何调用它:

    push   OFFSET prompt
    call   STRQRY
    call   writedec         <<< Length given by ReadString
    push   OFFSET response
    call   STRLEN