如何计算8086 ALP中字符串中的元音数量?

问题描述 投票:2回答:1

我编写了一个汇编程序,用于计算用户读取的字符串中的元音数量。读取字符串和计算长度工作正常。但是当比较字符串的字符时,它对前两个字符不起作用。这是我的代码。

.MODEL small
.STACK
.DATA
 input db 10,?
 length db ?
 count db ?
.CODE
.STARTUP 
 ;reading string
 mov dx,00h
 mov dx,offset input
 mov ah,0Ah
 int 21h 

 ;calculating length
 mov length,00h
 mov si,offset input+2

 ;checking for vowels
 loopi: cmp [si],'$'
    je next
    add length,01h
    inc si
    loop loopi
 next:
    mov cx,00h
    mov cl,length 

    mov si,offset input+2 
    mov count,00h
 counting:cmp [si],'a'
      je count1 
      cmp [si],'e'
      je count1
      cmp [si],'i'
      je count1
      cmp [si],'o'
      je count1
      cmp [si],'u'
      je count1
      inc si
      loop counting
      cmp cl,00h
      je exit
  count1:inc count 
      inc si
     loop counting 
 exit: 
.EXIT
 end

此代码不比较/检查字符串的前两个字符。有人可以尽快帮助我吗?任何帮助将非常感激。非常感谢。

assembly user-input x86-16 emu8086
1个回答
2
投票

读取字符串和计算长度工作正常。但是在比较字符串的字符时,它不适用于前两个字符。

碰巧,正是比较部分很好!你的麻烦从输入和存在开始,因为你不明白问题标记在汇编编程中的作用。

input db 10,?
length db ?
count db ?

在所有这些行中,问号?表示单个字节,大多数(如果不是全部)汇编器将初始化为零值0。您得到的是:

input  db 10, 0
length db 0
count  db 0

这对于长度和计数是好的,但对于应该是the DOS buffered input function 0Ah的输入缓冲区的输入则不是这样。您没有真正需要的存储空间。这是被错误覆盖的长度,计数等内存!

解决方案是input db 10, 0, 10 dup (?)。这允许输入9个字符。为什么9?因为DOS总是将一个回车符13附加到输入,并且该回车在10 dup (?)定义的这个10字节存储空间中也需要一个字节。

此回车也解释了为什么长度计算失败的原因。当您搜索ASCII码13时,您正在搜索“$”。

当然,计算长度是多余的,因为DOS已经通知了你。输入结构的第二个字节是长度。

mov cx, 0
mov cl, [input+1] ; length 

全部一起:

.DATA
 input  db 10, 0, 10 dup (?)
 count  db ?
.CODE
.STARTUP 
 ;reading string
    mov  dx, offset input
    mov  ah, 0Ah
    int  21h 

 ;checking for vowels
    xor  cx, cx            ; Also clears the CX register like `mov cx, 0`
    mov  count, cl         ; Count = 0
    mov  si, offset input+2 
    mov  cl, [si-1]        ; length is 2nd byte
 counting:
    cmp  [si], 'a'
    je   count1 
    cmp  [si], 'e'
    je   count1
    cmp  [si], 'i'
    je   count1
    cmp  [si], 'o'
    je   count1
    cmp  [si], 'u'
    je   count1
    inc  si
    loop counting
    cmp  cl, 0        \ You can replace these 2 by
    je   exit         / a single `jmp exit`
 count1:
    inc  count 
    inc  si
    loop counting 
 exit: 
.EXIT

更好的解决方案

  • 不使用慢loop指令
  • 最小化内存访问
  • 使用像lodsb这样的字符串原语
  • 如果字符串为空则不会失败!
  • 尽量减少跳跃的数量

在这里介绍:

 ;checking for vowels
    cld                ; For completeness because `lodsb` depends on it
    mov  si, offset input+2 
    mov  dl, -1
 vowel:
    inc  dl
 other:
    lodsb              ; This is `mov al, [si]` followed by `inc si`
    cmp  al, 'a'
    je   vowel 
    cmp  al, 'e'
    je   vowel
    cmp  al, 'i'
    je   vowel
    cmp  al, 'o'
    je   vowel
    cmp  al, 'u'
    je   vowel
    cmp  al, 13
    jne  other
    mov  count, dl
© www.soinside.com 2019 - 2024. All rights reserved.