asm x86 32 位中的回文函数

问题描述 投票:0回答:1
    section .data
    msg1 db 'Introduce lenght !',0xA,0xD
    len1 equ $-msg1
    nl db 0xA,0xD
    pal db 'Is palindrome',0xA,0xD
    lenpal equ $-pal
    nonpal db 'Is not palindrome ',0xA,0xD
    lennonpal equ $-nonpal
    poz db 0
section .bss
    index1 resb 1
    index2 resb 1
    lenght resb 1
    array times 10 resb 1
    sep resb 1
section .text
    global _start
_start:

    mov eax,4
    mov ebx,1
    mov ecx,msg1
    mov edx,len1
    int 0x80

    mov eax,3
    mov ebx,0
    mov ecx,lenght
    mov edx,1
    int 0x80

    mov cl,[lenght]
    sub cl,'0'
    mov [lenght],cl

    mov [index2], byte 0
    mov al,[index2]
    add al,[lenght]
    mov [index2],al
    

    mov eax,3
    mov ebx,0
    mov ecx,sep
    mov edx,1
    int 0x80


read:
    mov al,[poz]
    inc al
    mov [poz],al

    mov eax,3
    mov ebx,0
    mov ecx,array
    add ecx,[poz]
    mov edx,1
    int 0x80

    mov cl,[lenght]
    dec cl
    mov [lenght],cl
    cmp byte [lenght],0
    jne read

print_array:
    mov eax,4
    mov ebx,1
    mov ecx,array
    mov edx,[lenght]
    int 0x80

    mov [index1], byte 0
    mov bl,[index1]
    inc bl
    mov [index1],bl    
verify_pal:
    ; mov eax, array


    mov esi ,array
    mov ebx,[index1]
    add esi,ebx

    mov bl,[esi]

    mov edi ,array
    mov ebx,[index2]
    add edi,ebx

    mov cl,[edi]

    cmp bl,cl
    jne not_a_pal

    mov bh,[index1]
    inc bh
    mov [index1],bh
    
    mov ch,[index2]
    dec ch
    mov [index2],ch

    mov al,[index1]
    cmp al,[index2]
    jng verify_pal

is_pal:

    mov eax,4
    mov ebx,1
    mov ecx,pal
    mov edx,lenpal
    int 0x80
    jmp exit

not_a_pal:
    mov eax,4
    mov ebx,1
    mov ecx,nonpal
    mov edx,lennonpal
    int 0x80
    jmp exit
exit:
    mov eax,1
    mov ebx,0
    int 0x80

有人可以告诉我我的程序出了什么问题吗?我是一个完全的初学者,我试图弄清楚汇编是如何工作的,但这段代码总是以段错误结束。

assembly x86 segmentation-fault nasm palindrome
1个回答
0
投票

我的程序出了什么问题?

    jmp exit
exit:

跳转到正下方的标签是多余的操作。执行可能会失败。

mov bl,[esi]

mov edi ,array
mov ebx,[index2]

在回文检查器中,您将第一个字节加载到 BL 寄存器中,但在销毁 BL 后立即将 index2 变量加载到 EBX 寄存器中。请记住,BL 不是一个独立的寄存器,而是 32 位寄存器 EBX 的最低 8 位的名称。

此代码总是以 seg 错误结束。

发生分段错误是因为您使用 resb 指令将 pozlenghtindex1index2 变量定义为

byte
。通常这可能没问题,但稍后在程序中您将在双字大小的操作中使用这些字节大小的变量!由于您的汇编器 (NASM) 不会为您检查大小,因此它会很乐意从字节大小的变量中读取双字(只需添加内存中恰好跟随的 3 个字节)。在这种情况下,像 FASM 这样与 NASM 非常接近的汇编器会警告您。
接下来是出错的部分:

mov ecx,array
add ecx,[poz]
mov ecx,array
mov edx,[lenght]
mov esi ,array
mov ebx,[index1]
add esi,ebx
mov bl,[esi]
mov edi ,array
mov ebx,[index2]
add edi,ebx
mov cl,[edi]

对于其中一些,您可以通过简单地将变量的字节零扩展到寄存器的双字来摆脱它:

movzx edx, byte [length]
movzx ebx, byte [index1]
movzx ebx, byte [index2]

但是因为您正在编写32位代码,所以更好的解决方案是将(许多/大部分)变量定义为双字。

section .data poz dd 0 ... section .bss index1 resd 1 index2 resd 1 length resb 1 array times 10 resb 1 sep resb 1
冗余会使你的程序变得臃肿。

您使用的指令比所需的多得多,特别是在以下四行中,最终归结为将数字 1 放入

index1 变量中:

mov [index1], byte 0 mov bl,[index1] inc bl mov [index1],bl

接下来是所有这些冗余代码片段的列表,我添加了正确的替换指令,以适合新的数据声明(三个双字变量):

mov cl,[lenght] sub byte [length], '0' sub cl,'0' mov [lenght],cl mov [index2], byte 0 movzx eax, byte [length] mov al,[index2] mov [index2], eax add al,[lenght] mov [index2],al mov al,[poz] inc dword [poz] inc al mov [poz],al mov cl,[lenght] dec byte [length] dec cl jnz read mov [lenght],cl cmp byte [lenght],0 jne read mov [index1], byte 0 mov dword [index1], 1 mov bl,[index1] inc bl mov [index1],bl mov esi ,array mov esi, [index1] mov ebx,[index1] mov bl, [array + esi] add esi,ebx mov bl,[esi] mov edi ,array mov edi, [index2] mov ebx,[index2] mov cl, [array + edi] add edi,ebx mov cl,[edi] mov bh,[index1] inc esi inc bh mov [index1], esi mov [index1],bh mov ch,[index2] dec edi dec ch mov [index2], edi mov [index2],ch mov al,[index1] cmp esi, edi cmp al,[index2] jb verify_pal jng verify_pal Nice and clean does it. - > mov eax,3 > mov ebx,0 > mov ecx,sep > mov edx,1 > int 0x80 I suppose that *sep* stands for 'separator', but I don't see any use of this in the rest of your program. For clarity, it is always best to not keep such fragments lying around.
    
© www.soinside.com 2019 - 2024. All rights reserved.