循环以检查程序集中的小写字母

时间:2015-12-16 00:35:22

标签: assembly x86 nasm

我正在编写一个循环作为更大程序的一部分,检查第二个参数是否包含任何大写字母(如果是,程序退出)。这是我到目前为止所拥有的。我已经标记了我遇到问题的代码部分。

%include "asm_io.inc"
SECTION .data
err1: db "Incorrect number of command line arguments",10,0
err2: db "2nd argument lenght more than 20",10,0
err3: db "Upper-case letter found!!!",10,0
strt: db "ho",10,0

SECTION .bss
N: resd 1

SECTION .text 
    global  asm_main

asm_main:
   enter 0,0
   pusha

   mov eax, dword [ebp+8]
   cmp eax, dword 2
   jne ERR1

   mov ebx, dword [ebp+12]   ; 24 to 37 calculates the length of 2nd argument
   mov eax, dword [ebx+4]
   mov edi, eax
   sub ecx, ecx
   sub al, al
   not ecx
   cld
   repne scasb
   not ecx 
   dec ecx
   mov eax, ecx
   cmp eax, dword 20
   ja ERR2

   mov [N], dword eax       ;line 39 to 54 makes sure that all letters are lowercase
   call print_int
   mov ebx, N
   call print_int
   mov ebx, dword [ebp+12]
   mov eax, dword [ebx+4]

;------------------------- Code that I am having problems with
LOOP: 
   mov bl, byte[eax]
   cmp bl, 0x61
   jb ERR3
   cmp bl, 0x7A
   jb ERR3
   add eax, 4
   add ecx,1
   cmp ecx, N
   jb LOOP
;---------------------------------------------------------------

   mov eax,  0
   mov eax, strt
   call print_nl
   call print_string
   jmp asm_main_end

 ERR1:
   mov eax, err1
   call print_string
   jmp asm_main_end

 ERR2:
   mov eax, err2
   call print_string
   jmp asm_main_end

 ERR3: 
   mov eax, err3
   call print_string
   jmp asm_main_end

 asm_main_end:
   call print_nl
   popa                  
   leave                     
   ret

但即使我的第二个参数是abcd,循环仍会跳转到ERR3。我有什么想法可能做错了吗?我正在运行redhat-linux,nas 2.10.07。 编辑:N是第二个参数的正确长度。

1 个答案:

答案 0 :(得分:2)

我认为你正在寻找类似的东西:

  xor ecx, ecx   ; Initialize the counter ECX to zero
LOOP:
  mov bl, byte[eax]
  cmp bl, 'A'
  jb .CONT       ; If we are below 'A' we are not a capital, continue to next char
  cmp bl, 'Z'    ; We are >= 'A' here, but we need to check if we are <= 'Z' 
  jbe ERR3       ; If we are <= 'Z' then we must be a capital so Goto ERR3
.CONT:           ; If there was no error we reach here
  inc eax        ; Goto next character
  inc ecx        ; We want to do another loop
  cmp ecx, [N]   ; Compare to what is variable [N], not its pointer
  jbe LOOP       ; Loop while ECX <= N (N = strlen not including nul terminator) 

我已将评论放入代码中进行解释。此代码未经过简化,我尝试以与您当前编写的代码类似的方式生成代码。

一般的想法是比较A&#39; A&#39;和&#39; Z&#39;。如果我们在那个范围内,那么我们就会出错。首先比较我们是否小于&#39; A&#39;。如果我们不能成为大写字母,因为下面没有大写字母&#39; A&#39; (在ASCII表中)。如果我们低于&#39; A&#39;我们继续下一个角色。如果我们不低于&#39; A&#39;我们继续检查是否确实是&lt; =&#39; Z&#39;。如果我们那么我们必须是大写字母然后我们产生错误。否则我们继续下一个角色。

一种更先进的方法(我在上面提到的方法)是减去A&#39;从 BL 然后使用无符号比较将其与25(&#39; Z&#39; - &#39; A&#39;)进行比较。如果 BL 低于或等于25,则 BL 是大写字母。代码看起来像这样:

     xor ecx, ecx
   LOOP:
     mov bl, byte [eax]
     sub bl, 'A'              ; Normalize BL
     cmp bl, 'Z'-'A'          ; 'Z'-'A' = 25 (alphabet between 0 and 25 inclusive)
     jbe ERR3                 ; If BL <= 25 (unsigned comparison!) then BL 
                              ; was a capital letter

     inc eax
     inc ecx
     cmp ecx, [N]
     jbe LOOP