需要从汇编中的字符串中删除所有非字母元素 [英] Need to remove all non letter elements from a string in assembly

查看:137
本文介绍了需要从汇编中的字符串中删除所有非字母元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编写此汇编代码后,我无法使用此选项来删除非字符字母.它将在所有比较的字符串中进行迭代,然后显示相同的字符串,且未删除任何非字符. 我正在尝试将字母字符放入tempString中,然后可以将其移动到edx以进行显示.

它接收一个字符串并删除所有非字母字符
然后使用另一个使用writestring并注册edx

的过程显示新的字符串


;// ------------------------------------------------------------------------------
option3 PROC
;// Description: removes all non-letter elements. There is no requirement for
;// option2 to have been executed.
;// Receives: ecx - length of string
;// edx - offset of string
;// ebx - offset of string length variable
;// esi preserved
;// Returns: nothing, but the string will have all non-letter elements removed

.data


.code

push esi
call option5

L3:
mov al, byte ptr [edx+esi]

cmp al, 41h
jb notletter
cmp al, 5Ah
ja notletter
cmp al, 61h
jb notletter
cmp al,7Ah
ja notletter


mov byte ptr [edx+esi], al

notletter:
inc esi
loop L3


pop esi
call option5
call waitmsg

option3 ENDP

解决方案

首先,将其视为从一个位置复制到同一位置;需要复制的字节不会被复制.为此,您需要2个寄存器-一个用于跟踪从哪里获取下一个字节(例如,可能是esi),另一个用于跟踪在哪里存储下一个字节/字母(例如,可能是edi).

第二,您的是字母"分支是不正确的(例如,字母"A"或值0x41小于字母"a"或值0x61).它需要更像是:

    cmp al,'A'       ;Is the value too low to be any letter?
    jb .notLetter    ; yes
    cmp al,'z'       ;Is the value too high to be any letter?
    ja .notLetter    ; yes
    cmp al,'Z'       ;Is the value low enough to be a capital letter?
    jbe .isLetter    ; yes
    cmp al,'a'       ;Is the value high enough to be a lower case letter?
    jae .isLetter    ; yes
                     ; no, not a letter
.notLetter:

例如(NASM):

;Inputs:
; ecx    Length of original string
; esi    Address of original string
;
;Outputs
; edi    Length of new string
; ebx    Address of new string

filterString:
    mov edi,esi      ;edi = address to store string (same address as original string)
    mov ebx,esi      ;ebx = address of both strings (used later)
    jecxz .done      ;Do nothing if the original string has zero length
    cld

.nextByte:
    lodsb            ;AL = next byte, ESI incremented
    cmp al,'A'       ;Is the value too low to be any letter?
    jb .doneByte     ; yes, not a letter
    cmp al,'z'       ;Is the value too high to be any letter?
    ja .doneByte     ; yes, not a letter
    cmp al,'Z'       ;Is the value low enough to be a capital letter?
    jbe .isLetter    ; yes, it's a capital letter
    cmp al,'a'       ;Is the value high enough to be a lower case letter?
    jb .doneByte     ; no, not a letter
                     ; yes, it's a lower case letter
.isLetter:
    stosb            ;Store AL at EDI, and increment EDI

.doneByte:
    loop .nextByte
.done:
    sub edi,ebx      ;edi = length of new string
    ret

with writing this assembly code i cant get this option to work with the removing a non character letter. it will either iterate through the string with all the comparisons and then display the same string with no non characters removed. I'm trying to get the letter characters into a tempString that i can then move to edx to be displayed.

it takes in a string and removes all non letter characters
then displays the new string using another procedure that uses writestring and register edx


;// ------------------------------------------------------------------------------
option3 PROC
;// Description: removes all non-letter elements. There is no requirement for
;// option2 to have been executed.
;// Receives: ecx - length of string
;// edx - offset of string
;// ebx - offset of string length variable
;// esi preserved
;// Returns: nothing, but the string will have all non-letter elements removed

.data


.code

push esi
call option5

L3:
mov al, byte ptr [edx+esi]

cmp al, 41h
jb notletter
cmp al, 5Ah
ja notletter
cmp al, 61h
jb notletter
cmp al,7Ah
ja notletter


mov byte ptr [edx+esi], al

notletter:
inc esi
loop L3


pop esi
call option5
call waitmsg

option3 ENDP

解决方案

First, think of this as copying from one place to the same place; where bytes that need to be ignored are not copied. You need 2 registers for this - one to keep track of where to get the next byte (e.g. maybe esi), and one to keep track of where to store the next byte/letter (e.g. maybe edi).

Second, your "is it a letter" branches aren't right (e.g. the letter 'A' or the value 0x41 will be less than the letter 'a' or the value 0x61). It needs to be more like:

    cmp al,'A'       ;Is the value too low to be any letter?
    jb .notLetter    ; yes
    cmp al,'z'       ;Is the value too high to be any letter?
    ja .notLetter    ; yes
    cmp al,'Z'       ;Is the value low enough to be a capital letter?
    jbe .isLetter    ; yes
    cmp al,'a'       ;Is the value high enough to be a lower case letter?
    jae .isLetter    ; yes
                     ; no, not a letter
.notLetter:

For example (NASM):

;Inputs:
; ecx    Length of original string
; esi    Address of original string
;
;Outputs
; edi    Length of new string
; ebx    Address of new string

filterString:
    mov edi,esi      ;edi = address to store string (same address as original string)
    mov ebx,esi      ;ebx = address of both strings (used later)
    jecxz .done      ;Do nothing if the original string has zero length
    cld

.nextByte:
    lodsb            ;AL = next byte, ESI incremented
    cmp al,'A'       ;Is the value too low to be any letter?
    jb .doneByte     ; yes, not a letter
    cmp al,'z'       ;Is the value too high to be any letter?
    ja .doneByte     ; yes, not a letter
    cmp al,'Z'       ;Is the value low enough to be a capital letter?
    jbe .isLetter    ; yes, it's a capital letter
    cmp al,'a'       ;Is the value high enough to be a lower case letter?
    jb .doneByte     ; no, not a letter
                     ; yes, it's a lower case letter
.isLetter:
    stosb            ;Store AL at EDI, and increment EDI

.doneByte:
    loop .nextByte
.done:
    sub edi,ebx      ;edi = length of new string
    ret

这篇关于需要从汇编中的字符串中删除所有非字母元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆