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