汇编回文检测程序空格跳过逻辑报错求助
回文检测汇编程序的空格处理与跳转错误问题
我写了个回文检测汇编程序,单个单词能正常识别,但带空格的句子就不行。我加了skip_space1和skip_space2逻辑想跳过空格,没解决问题;而且在跳过语句末尾加jmp .loop时,弹出两个报错:
palindrom0.asm:61: error: symbol skip_space2.loop not defined
palindrom0.asm:65: error: symbol `skip_space1.loop' not defined
相关代码如下:
call getaddr ; push on the stack the runtime address of format and jump to getaddr format db "evil olive" length equ $ - format db 0xA, 0 getaddr: mov ecx, length ; ecx = length shr ecx, 1 ; ecx = ecx >> 1 = ecx / 2 jecxz pass ; jump if ecx is zero ; jump if ecx = 0 mov esi, [esp] ; esi = *(int*)esp = format lea edi, [esi+length-1] ; edi = esi + length - 1 .loop mov al, [esi] ; al = *(char*)esi mov ah, [edi] ; ah = *(char*)edi cmp al, ' ' je skip_space1 cmp ah, ' ' je skip_space2 cmp al, ah jne not_pass inc esi ; esi++ dec edi ; edi-- loop .loop pass: ... skip_space2: dec edi jmp .loop skip_space1: inc esi jmp .loop
问题分析与解决
1. 跳转报错的原因
汇编器里以.开头的局部标签,作用域仅限于当前父标签范围。你的.loop是getaddr下的局部标签,而skip_space1、skip_space2是全局标签,直接写jmp .loop时,汇编器会默认查找当前标签(比如skip_space1)下的.loop,自然找不到,所以报符号未定义。
解决方法:跳回getaddr里的.loop时,要明确指定父标签,写成jmp getaddr.loop。
2. 空格处理逻辑的漏洞
原代码遇到空格只跳一次,要是连续多个空格,下次循环还是会读到空格,导致错误的字符对比;另外也没检查指针是否越界,可能访问非法内存。
修正后的代码
call getaddr ; push runtime address of format to stack, jump to getaddr format db "evil olive" length equ $ - format db 0xA, 0 getaddr: mov ecx, length ; init ecx with string length shr ecx, 1 ; ecx = length / 2, half the checks needed jecxz pass ; if length is 0/1, directly pass mov esi, [esp] ; esi = start address of string lea edi, [esi+length-1] ; edi = end address of string .loop mov al, [esi] ; load char from start mov ah, [edi] ; load char from end ; Handle spaces at the start pointer .skip_space1: cmp al, ' ' jne .check_end_space inc esi cmp esi, edi ; stop if pointers cross jge pass mov al, [esi] jmp .skip_space1 .check_end_space: ; Handle spaces at the end pointer .skip_space2: cmp ah, ' ' jne .compare_chars dec edi cmp esi, edi ; stop if pointers cross jge pass mov ah, [edi] jmp .skip_space2 .compare_chars: cmp al, ah jne not_pass ; chars don't match, not a palindrome inc esi dec edi loop .loop ; continue checking until ecx is 0 pass: ; logic for palindrome pass case ... not_pass: ; logic for not palindrome case ...
修正说明
- 把空格处理改成循环,直到遇到非空格字符或者指针相遇,解决连续空格的问题。
- 用嵌套的局部标签(
.skip_space1、.skip_space2)属于getaddr,跳转时不用指定父标签,避免符号错误。 - 增加指针越界检查,防止非法内存访问。
- 调整逻辑顺序,让代码更清晰。
内容的提问来源于stack exchange,提问作者wojst
相关产品推荐
相关产品推荐

