Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 13, средняя оценка - 4.85
sasha_rastich
0 / 0 / 0
Регистрация: 02.01.2009
Сообщений: 3
#1

Вызов функций через таблицу прерываний - C++

10.01.2009, 20:55. Просмотров 1681. Ответов 2
Метки нет (Все метки)

Уважаемые участники форума cyberforum.ru, очень нужна ваша помощь. Столкнулся с такой вот проблемой: написал класс обработки 64-битных чисел со знаком с применением функций состоящих из ассемблерных вставок. Заменил вызовы этих функций на вызовы через таблицу векторов прерываний. В функции класса Converting(char*):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
int AsmBinNum::Converting(char* line) {
    int i;
    //---------------
    length = strlen(line);
    sign = 0;
    result = 0;
    error = 0;
    //sign test:
    if (line[0] == '-') {
        sign = 1;
        for (i = 0; i < length; i++)
            line[i] = line[i + 1];
        length--;
    }
    //symbol count test:
    if (length > size) {
        cout << "Error: too many symbols\n";
        return 1;
    }
    //zero test:
    if (sign == 0) {
        if (length != 1 && line[0] == '0') {
            cout << "Error: nonnumeric symbol\n";
            return 2;
        }
    }
    else {
        if (line[0] == '0') {
            cout << "Error: nonnumeric symbol\n";
            return 2;
        }
    }
    //calling of Newdig():
    geninterrupt(0x70);
    //Newdig();
    if (error == 1) {
        cout << "Error: nonnumeric symbol\n";
        return 3;
    }
    //calling of BCDBin64():
    geninterrupt(0x71);
    //BCDBin64();
    if (error == 1) {
        cout << "Error: overflow\n";
        return 3;
    }
    if (sign == 1)
        geninterrupt(0x74);//ComCode();
    x = result;
    return 0;
}
возникает зависание при попытке присваивания.
Уже два дня пытаюсь понять в чем проблема. Если закомментировать вызов BCDBin64 через прерывание то все нормально работает. Если закомментировать присваивание и откомментировать вызов BCDBin64, то тоже все работает. Где тут ошибка?
Код BCDBin64():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
void interrupt BCDBin64(...) {
    asm {
        mov bx,offset num-8
        mov di,offset result
        mov cx,[length]
        dec cx
        jcxz label2
    label1:
        add bx,8
    }
        //MulBy10();
        geninterrupt(0x72);
    asm {
        loop label1
    label2:
        push [word (bx+8)]
        push [word (bx+10)]
        push [word (bx+12)]
        push [word (bx+14)]
        dec [length]
        jnz label3
        xor ax,ax
        xor bx,bx
        jmp label4
    label3:
    }
        BCDBin64();
    asm {
    label4:
        pop ax
        pop bx
        pop cx
        pop dx
        add [word (di)],dx
        adc [word (di+2)],cx
        adc [word (di+4)],bx
        adc [word (di+6)],ax
        jc overflow
        cmp [sign],1
        jz negative
        mov ax,[word (di+6)]
        test ax,0x8000
        jz label5
        jmp overflow
    negative:
        mov ax,[word (di+6)]
        cmp ax,0x8000
        jb label5
        ja overflow
        mov ax,[word (di+4)]
        cmp ax,0
        ja overflow
        mov ax,[word (di+2)]
        cmp ax,0
        ja overflow
        mov ax,[word (di)]
        cmp ax,1
        jb label5
    overflow:
        mov [error],1
    }
    label5:
}
Функция Newdig():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void interrupt Newdig(...) {
    asm {
        mov cx,[length]
        mov di,offset line
        add di,cx
        mov si,offset num
        shl cx,3
        add si,cx
        shr cx,3
    label1:
        dec di
        sub si,8
        sub [byte (di)],0x30
        jnc label2
        mov [error],1
        jmp exit
    label2:
        cmp [byte (di)],0xA
        jc label3
        mov [error],1
        jmp exit
    label3:
        xor ah,ah
        mov al,[byte (di)]
        mov [word (si)],ax
        mov [word (si+2)],0
        mov [word (si+4)],0
        mov [word (si+6)],0
        loop label1
    }
exit:
}
Код MulBy10():
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
void interrupt MulBy10(...) {
    asm {
        shl [word (bx)],1
        rcl [word (bx+2)],1
        rcl [word (bx+4)],1
        rcl [word (bx+6)],1
        jc label1
        mov ax,[word (bx)]
        mov [word (buffer)],ax
        mov ax,[word (bx+2)]
        mov [word (buffer+2)],ax
        mov ax,[word (bx+4)]
        mov [word (buffer+4)],ax
        mov ax,[word (bx+6)]
        mov [word (buffer+6)],ax
        shl [word (bx)],1
        rcl [word (bx+2)],1
        rcl [word (bx+4)],1
        rcl [word (bx+6)],1
        jc label1
        shl [word (bx)],1
        rcl [word (bx+2)],1
        rcl [word (bx+4)],1
        rcl [word (bx+6)],1
        jc label1
        mov ax,[word (bx)]
        add [word (buffer)],ax
        mov ax,[word (bx+2)]
        adc [word (buffer+2)],ax
        mov ax,[word (bx+4)]
        adc [word (buffer+4)],ax
        mov ax,[word (bx+6)]
        adc [word (buffer+6)],ax
        jnc label2
    label1:
        mov [error],1
        jmp exit
    }
    label2:
    asm {
        mov ax,[word (buffer)]
        mov [word (bx)],ax
        mov ax,[word (buffer+2)]
        mov [word (bx+2)],ax
        mov ax,[word (buffer+4)]
        mov [word (bx+4)],ax
        mov ax,[word (buffer+6)]
        mov [word (bx+6)],ax
    }
exit:
}
x - элемент класса; result, line, length, num - глобальные переменные
Спасибо

Добавлено через 1 минуту 49 секунд
При попытке присваивания x = result перед выходом из функции*

Добавлено через 1 час 27 минут 39 секунд
И если закомментировать в BCDBin64 4 push'а и 4 pop'а то тоже все нормально, не зависает. Ну хоть скажите где именно может быть ошибка.

Добавлено через 2 часа 7 минут 57 секунд
Хоть кто-нибудь что-нибудь...................................

Добавлено через 52 минуты 30 секунд
если ввести число 10000000000000000 и больше или отрицательное то опять таки волшебным образом работает.....

Добавлено через 1 минуту 7 секунд
если переслать перед присваиванием result в регистры то видно что там правильное значение

Добавлено через 2 минуты 38 секунд
ошибка где то здесь:
C++
1
2
3
fld qword ptr DGROUP:_result
fstp    qword ptr [si]
fwait
это команда присваивания на ассемблере

Добавлено через 35 секунд
Кто-нибудь прервите мой монолог

Добавлено через 1 минуту 35 секунд
КАК МОЖЕТ ВИСНУТЬ ПРИСВАИВАНИЕ???????
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.01.2009, 20:55     Вызов функций через таблицу прерываний
Посмотрите здесь:

Объявление и вызов функций? C++
Вызов функций-элементов в С++ C++
Вызов функций C++
Определение и вызов функций C++
C++ Вызов функций
Вызов функций C++
Вызов функций из файлов. C++
Затраты на вызов функций C++
Вызов функций C++
Определение и вызов функций C++
C++ Вызов функций
C++ Вызов виртуальных функций

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vourhey
Почетный модератор
6474 / 2249 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
10.01.2009, 21:11     Вызов функций через таблицу прерываний #2
А там точно fwait нужен? Для своего проца, я вообще без него когда-то делал. На современных он, вроде, автоматически работает. Или я ошибаюсь. Не помню уже...
Вообще, фиг знает. Просмотреть листинг у меня времени не хватает, к сожалению.
sasha_rastich
0 / 0 / 0
Регистрация: 02.01.2009
Сообщений: 3
10.01.2009, 23:21  [ТС]     Вызов функций через таблицу прерываний #3
Ну это так транслируется x = result. Машина ж должна сама все правильно делать? А она зависает..... (((((

Добавлено через 2 минуты 11 секунд
оно не только на присваивании но и на cout << result в том месте зависает

Добавлено через 1 час 53 минуты 51 секунду
Я НАШЕЛ ОШИБКУ )))))))))) Дело не в присваивании... Я забывал возвращать старый вектор... Спасибо всем кто наблюдал за этой драмой... но со счастливым концом ))) Теперь дядя мне не поставит шайбу....
Yandex
Объявления
10.01.2009, 23:21     Вызов функций через таблицу прерываний
Ответ Создать тему
Опции темы

Текущее время: 06:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru