Ошибка сегментации NASM (ядро сброшено) - PullRequest
0 голосов
/ 04 мая 2020

Итак, я хочу создать программу, которая позволит пользователю вводить матрицу 4х5. Я объявил «указатели» для указания c строк и «указатель» на эти указатели, чтобы иметь доступ к каждой строке, используя один указатель. Я создал строки, потому что я хочу проверить символы в этих строках (пользователь может вводить только цифры и + или - в качестве первого символа). Поэтому у меня возникает проблема, когда я проверяю первый символ (это должен быть + или -), и если пользователь не вводит + или -, я вижу ошибку сегментации (ядро сброшено). Я использую Ubuntu. (Engli sh не мой родной язык, и если я допустил ошибку, просто не беспокойтесь об этом))).

; Task: write a program that allows to enter 2-D array 4x5. Show only 2 first columns.
;   # # # # #  
;   # # # # #
;   # # # # #
;   # # # # # 


section .bss ; The section intended for uninitilizated data
    string_00 resb 7
    string_01 resb 7
    string_02 resb 7
    string_03 resb 7
    string_04 resb 7

    string_10 resb 7
    string_11 resb 7
    string_12 resb 7
    string_13 resb 7
    string_14 resb 7

    string_20 resb 7
    string_21 resb 7
    string_22 resb 7
    string_23 resb 7
    string_24 resb 7

    string_30 resb 7
    string_31 resb 7
    string_32 resb 7
    string_33 resb 7
    string_34 resb 7

section .data ; The section designed for using initilizated data
    GreenColor db 0x1b, '[32m' ; The string that can change text color to green
    lenGreenColor equ $ - GreenColor ; The lenth of this string

    RedColor db 0x1b, '[31m' ; The string that can change text color to red (used if user will enter incorrect data)
    lenRedColor equ $ - RedColor ; The lenth of this string

    Task db 'This program allows you to enter matrix 4x5 and show only 2 first colums.', 0xa ; Just a string that shows my task
    lenTask equ $ - Task ; The lenth of this string

    Warning db 'Enter 16-bit numbers (from -32767 to +32768) and enter the sign of number, please.', 0xa ; Warning, I chose 16-bit number because the bigger
    lenWarning equ $ - Warning ; The lenth of this string                                                ; numbers will be processed in the same way, but long
                                                                                                         ; numbers are not necessary    

    ErrorSign db 'You should use the sign of the number ( + or - )!', 0xa ; An error message to user if he did not use the number sign
    lenErrorSing equ $ - ErrorSign ; THe lenth of this message

    pointer_0 dd string_00, string_01, string_02, string_03, string_04
    pointer_1 dd string_10, string_11, string_12, string_13, string_14
    pointer_2 dd string_20, string_21, string_22, string_23, string_24
    pointer_3 dd string_30, string_31, string_32, string_33, string_34

    pointer dd pointer_0, pointer_1, pointer_2, pointer_3

    external_counter db 0
    internal_counter db 0

section .text
    global _start
_start:
    mov edx, lenGreenColor
    mov ecx, GreenColor
    call _print

    mov edx, lenTask
    mov ecx, Task
    call _print

    mov edx, lenWarning
    mov ecx, Warning
    call _print

    call _check



    mov ebx, 0
    mov eax, 1
    int 0x80

_print:
    mov ebx, 1
    mov eax, 4
    int 0x80
    ret

_enter:
    mov edx, 7
    mov ebx, 0
    mov eax, 3
    int 0x80
    ret

_check:
    external_loop:
        mov eax, [pointer]
        mov ebx, [external_counter]
        mov esi, [eax + ebx * 4]

            internal_loop:
                mov ebx, [internal_counter]

                add ebx, ebx
                add ebx, ebx
                add ebx, ebx

                add esi, ebx
                mov ecx, esi
                call _enter

                cmp [esi], byte 43
                je norm_sign
                cmp [esi], byte 45
                je norm_sign


                xor esi, esi
                xor eax, eax
                xor ebx, ebx
                xor ecx, ecx
                xor edx, edx


                jmp _check
                    norm_sign:
                        ret

1 Ответ

1 голос
/ 04 мая 2020

У вас есть mov ebx, [external_counter], но также external_counter db 0. Поскольку ebx является 32-битным регистром, он будет читать 4 байта из external_counter. Проблема в том, что external_counter имеет длину всего 1 байт. Это означает, что вы собираетесь вытянуть 3 байта мусора в ebx, что отправит вас за пределы диапазона, когда вы выполните mov esi, [eax + ebx * 4]. Сделайте external_counter dd 0 вместо этого. (И похоже, что вы делаете ту же ошибку и с internal_counter.)

...