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

Как правильно вставить код на ассемблере? - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.83
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2012, 13:23     Как правильно вставить код на ассемблере? #1
Есть такой код:
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
struct
{
  unsigned long first_sect;
  unsigned nsect;
  void *buf;
} cb;
 
/**
* getboot
*
* Прочитать загрузочную запись
*
* int getboot(BOOT *boot, int drive);
*
*  boot   - указатель на буфер, в который
*           будет прочитана загрузочная запись
*
*  drive  - номер физического НМД
*           (0 - первый НМД, 1 - второй, ...)
**/
 
int getboot(BOOT *boot, int drive)
{
  cb.first_sect = 0;
  cb.nsect = 1;
  cb.buf = (void*)boot;
 
  _BX  = FP_OFF(&cb);
  _DS = FP_SEG(&cb);
  _CX  = 0xffff;
  _DX  = 0;
  _AX  = drive;
 
  asm int 25h
 
  // Извлекаем из стека оставшееся там после
  // вызова прерывания слово
  asm pop ax
  asm jc err
 
  return(0);
err:
  return(1);
}
В функции, как я понимаю, часть кода на ассемблере. Как его правильно вставить в код на MSVC?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
03.09.2012, 13:23     Как правильно вставить код на ассемблере?
Посмотрите здесь:

Как записать правильно? Программа работает но код наверно не верен. C++
C++ Как правильно отформатировать код?
Как правильно вставить переменную? C++
Правильно ли я понимаю ссылки и указатели. Работу с ними. Я сам прокомментировал код. Скажите правильно или нет. C++
C++ Как правильно засунуть две строчки в код программы?(
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2012, 15:48  [ТС]     Как правильно вставить код на ассемблере? #21
Цитата Сообщение от CheshireCat Посмотреть сообщение
А во-вторых, инструкция int (21h) относится к привилегированным, и попытка выполнить ее в юзер-моде вероятнее всего приведет к появлению такого премиленького окошечка: "Программа выполнила недопустимую операцию и будет закрыта."
Очень может быть, но как код до этого довести? Или, каким спобом прочитать логический сектор жёсткого диска?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Invader_Zim
Twilight Parasite
 Аватар для Invader_Zim
153 / 149 / 2
Регистрация: 21.07.2011
Сообщений: 907
03.09.2012, 15:57     Как правильно вставить код на ассемблере? #22
alsav22, есть сишные функции. Есть указатели. Первый сектор первого диска B1 кажись зовется
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2012, 16:01  [ТС]     Как правильно вставить код на ассемблере? #23
Цитата Сообщение от Invader_Zim Посмотреть сообщение
есть сишные функции
Какие?
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
03.09.2012, 16:09     Как правильно вставить код на ассемблере? #24
Цитата Сообщение от alsav22 Посмотреть сообщение
Или, каким спобом прочитать логический сектор жёсткого диска?
В современных ОС из юзер-моды - никак. Современные ОС (что Win, что Lin....) защищают систему от слишком шустрых ручонок пользователя, и подобные действия разрешают выполнить только из драйвера уровня ядра, который работает в кольце 0 при наивысших привилегиях.

Добавлено через 4 минуты
Да, вот еще какой совет могу дать: поставь себе виртуалку (VMWare, VirtualPC, etc...) или DosBox, надень на него MSDOS + Tubro C++, и экспериментируй, скока пожелаешь....
alsav22
03.09.2012, 16:19  [ТС]
  #25

Не по теме:

Цитата Сообщение от CheshireCat Посмотреть сообщение
Да, вот еще какой совет могу дать: поставь себе виртуалку (VMWare, VirtualPC, etc...) или DosBox, надень на него MSDOS + Tubro C++, и экспериментируй, скока пожелаешь....
В общем-то, это не мне нужно. ошибка при компиляции программы Не понятно только, если дают такие задания, как они представляют решение?

ForEveR
03.09.2012, 16:32
  #26

Не по теме:

alsav22,

#include <dos.h>
Однозначно намекает, что код должен работать под dosом.

alsav22
03.09.2012, 16:38  [ТС]
  #27

Не по теме:

Цитата Сообщение от ForEveR Посмотреть сообщение

Не по теме:

alsav22,
Однозначно намекает, что код должен работать под dosом.

А компилироваться где? Как её написать, чтобы скомпилировать?

ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
03.09.2012, 16:40     Как правильно вставить код на ассемблере? #28
alsav22, Что в досе работало - под тем и компилироваться. Что-нибудь Борландовское к примеру.
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2012, 16:48  [ТС]     Как правильно вставить код на ассемблере? #29
Цитата Сообщение от ForEveR Посмотреть сообщение
alsav22, Что в досе работало - под тем и компилироваться. Что-нибудь Борландовское к примеру.
По другому никак?
ForEveR
Модератор
Эксперт C++
 Аватар для ForEveR
7927 / 4709 / 318
Регистрация: 24.06.2010
Сообщений: 10,524
Завершенные тесты: 3
03.09.2012, 16:52     Как правильно вставить код на ассемблере? #30
alsav22, ну хм. если программа написана под dos, где она еще может компилироваться? Уже советовали с виртуальными машинками или с DosBOX-ом попробовать.
CheshireCat
Эксперт С++
2907 / 1235 / 78
Регистрация: 27.05.2008
Сообщений: 3,307
03.09.2012, 17:04     Как правильно вставить код на ассемблере? #31
Цитата Сообщение от alsav22 Посмотреть сообщение
Не понятно только, если дают такие задания, как они представляют решение?
Я бы, кстати, спросил бы об этом у "них"...... (препов? видать, заснувших лет этак 20 назад в состоянии анабиоза :-) - и так из этого состояния и не вышедших...)
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
03.09.2012, 17:38     Как правильно вставить код на ассемблере? #32
Не думаю, что чтение - привилегированная инструкция, привилегированным обычно делают запись (тот же sgtr доступен в user mode, а вот lgtr уже нет), поэтому тут проблем быть не должно. Думаю это может работать даже по Win XP (только что именно будет прочитано - вопрос)
Если сидишь под семеркой, то, как уже писали, поставь какой-нибудь DosBox (или DosEmu, не знаю есть ли он под винду), запусти там Turbo C++, компилируй и запускай.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
03.09.2012, 18:05     Как правильно вставить код на ассемблере? #33
Мне самому аж интересно стало, в общем в таком виде у меня скомпилилось
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
#include <stdio.h>
#include <dos.h>
 
struct
{
  unsigned long first_sect;
  unsigned nsect;
  void *buf;
} cb;
 
/**
* getboot
*
* Прочитать загрузочную запись
*
* int getboot(BOOT *boot, int drive);
*
*  boot   - указатель на буфер, в который
*           будет прочитана загрузочная запись
*
*  drive  - номер физического НМД
*           (0 - первый НМД, 1 - второй, ...)
**/
 
int getboot(char *boot, int drive) // лень было гуглить, что такое BOOT, поэтому просто заменил на char
{
  cb.first_sect = 0;
  cb.nsect = 1;
  cb.buf = (void*)boot;
 
  _BX  = FP_OFF(&cb);
  _DS = FP_SEG(&cb);
  _CX  = 0xffff;
  _DX  = 0;
  _AX  = drive;
 
  asm int 25h
 
  // Извлекаем из стека оставшееся там после
  // вызова прерывания слово
  asm pop ax
  asm jc err
 
  return(0);
err:
  return(1);
}
 
int main()
{
  char buf[512];
  int res = getboot(buf, 0);
 
  printf ("Res = %d\n", res);
 
  return 0;
}
результат компиляции
Как правильно вставить код на ассемблере?

и результат выполнения
Как правильно вставить код на ассемблере?

как видно, функция чтения вернула 1, значит что-то не так. Но мне уже лень разбираться, что не так

P.S. Linux - doxbox 0.74 и Borland C++ 3.1
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
03.09.2012, 18:28     Как правильно вставить код на ассемблере? #34
вот это
Assembler
1
jc err
очень смущает, т.к. pop не влияет на флаги, поэтому переход может происходить по совершенно другой причине.
Код сам писал?

Добавлено через 1 минуту
А не, все нормально, погуглил
Ошибки, возникающие в процессе INT 25H/26H, НЕ обрабатываются обработчиком кртических ошибок INT 24H . при выходе из INT 25H/26H, DOS-BIOS взводит флаг переноса (CF=1), когда встречается ошибка. Если установлен флаг CF:

AL = ошибка устройства (0-0cH) - аналогично битам 0-7 в DI для INT 24H - это
AL = один из кодов ошибок 13H-1fH (без 13H) в списке кодов ошибок DOS
AH = 80H = attachment failed to respond
AH = 40H = ошибка операции поиска на диске
AH = 08H = неверная контрольная сумма (CRC) при чтении дискеты
AH = 04H = запрошенный сектор не найден
AH = 03H = попытка записи на защищенную от записи дискету
AH = 02H = ошибка, отличная от перечисленных выше
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.09.2012, 19:20     Как правильно вставить код на ассемблере?
Еще ссылки по теме:

C++ Вставить массив в код
Как правильно прописать данный код программы? C++

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

Или воспользуйтесь поиском по форуму:
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
03.09.2012, 19:20  [ТС]     Как правильно вставить код на ассемблере? #35
Цитата Сообщение от Kastaneda Посмотреть сообщение
Код сам писал?
Нет. Вопрос на форуме ошибка при компиляции программы Код в инете выложен http://vmg.pp.ua/books/КопьютерыИсет...W/VIEWROOT.CPP Только я его немного подправил (чтобы ошибок компилятор не выдавал). У меня сейчас так компилируется (в студии) без ошибок:
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
struct
{
  unsigned long first_sect;
  unsigned nsect;
  void *buf;
} cb;
 
/**
* getboot
*
* Прочитать загрузочную запись
*
* int getboot(BOOT *boot, int drive);
*
*  boot   - указатель на буфер, в который
*           будет прочитана загрузочная запись
*
*  drive  - номер физического НМД
*           (0 - первый НМД, 1 - второй, ...)
**/
 
int getboot(BOOT *boot, unsigned char drive)
{
  cb.first_sect = 0;
  cb.nsect = 1;
  cb.buf = (void*)boot;
  __asm
{
    mov AH, 25H
    LDS BX, cb.buf
    mov CX,  1
    mov DX,  0
    mov AL,  drive
}
  __asm int 25h
 
  // Извлекаем из стека оставшееся там после
  // вызова прерывания слово
  __asm pop ax
  __asm jc err
  
  return 0;
err:
  return 1;
}
Но при запуске, после ввода буквы диска выскакивает ошибка: нарушение прав доступа при чтении 0xffffffff. Указывается эта строка:
C++
1
LDS BX, cb.buf
Тут нужно в DS:BX поместить адрес буфера, куда читать. Как правильно сделать в этом месте, не знаю.

Добавлено через 8 минут
Полный код у меня такой:
Код
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include <stdio.h>
#include <malloc.h>
#include <dos.h>
#include <cctype>
#include <iostream>
 
typedef struct _EBPB_ 
{
        unsigned sectsize;
        char clustsize;
        unsigned ressecs;
        char fatcnt;
        unsigned rootsize;
        unsigned totsecs;
        char media;
        unsigned fatsize;
        unsigned seccnt;
        unsigned headcnt;
        unsigned hiddensec_low;
        unsigned hiddensec_hi;
        unsigned long drvsecs;
} EBPB;
 
typedef struct BOOT_ 
{
        char jmp[3];
        char oem[8];
        EBPB bpb;
        char drive;
        char reserved;
        char signature;
        unsigned volser_lo;
        unsigned volser_hi;
        char label[11];
        char fat_format[8];
        char boot_code[450];
} BOOT;
 
//union REGS reg;
//struct SREGS segreg;
 
struct
{
  unsigned long first_sect;
  unsigned nsect;
  void *buf;
} cb;
 
/**
* getboot
*
* Прочитать загрузочную запись
*
* int getboot(BOOT *boot, int drive);
*
*  boot   - указатель на буфер, в который
*           будет прочитана загрузочная запись
*
*  drive  - номер физического НМД
*           (0 - первый НМД, 1 - второй, ...)
**/
 
int getboot(BOOT *boot, unsigned char drive)
{
  cb.first_sect = 0;
  cb.nsect = 1;
  cb.buf = (void*)boot;
  __asm
{
    mov AH, 25H
    LDS BX, cb.buf
    mov CX,  1
    mov DX,  0
    mov AL,  drive
}
  __asm int 25h
 
  // Извлекаем из стека оставшееся там после
  // вызова прерывания слово
  __asm pop ax
  __asm jc err
  
  return 0;
err:
  return 1;
}
 
 
int main() 
{
 
  setlocale(0, "");
  
  BOOT *boot_rec;
  int i, status;
  unsigned char drive;
  printf("Чтение загрузочной записи "
         "логического диска\n");
                        
// Заказываем буфер для чтения BOOT-записи.
  boot_rec = (BOOT*)malloc(sizeof(*boot_rec));
 
// Запрашиваем диск, для которого необходимо
// выполнить чтение загрузочной записи.
  printf("\nВведите обозначение диска, для просмотра "
         "загрузочной записи (A, B, ...):");
 
  std::cin >> drive;
 
// Вычисляем номер дисковода
 drive = toupper(drive) - 'A';
 
// Читаем загрузочную запись в буфер
 status = getboot((BOOT*)boot_rec, drive);
 
// Если произошла ошибка (например, неправильно указано
// обозначение диска), завершаем работу программы
  if(status) 
  {
        printf("nОшибка при чтении BOOT-сектора");
        exit(-1);
  }
 printf("nСодержимое BOOT-сектора для диска %c", drive +'A');
 printf("n"
                        "nOEM - название фирмы и версия DOS - ");
 
 for (i = 0; i < 8; i++) printf("%c", boot_rec->oem[i]);
 
  printf("nНомер диска                       - %x"
                        "nПризнак расширенной BOOT-записи   - %c"
                        "nСерийный номер диска              - %04X-%04X"
                        "nМетка диска                       - ",
                        (unsigned char)boot_rec->drive,
                        boot_rec->signature,
                        boot_rec->volser_hi,
                        boot_rec->volser_lo);
 
  for (i = 0; i < 11; i++) printf("%c", boot_rec->label[i]);
 
  printf("nФормат FAT                        - ");
  for (i = 0; i < 8; i++) printf("%c", boot_rec->fat_format[i]);
 
  printf("nnИнформация из BPB:n");
 
  printf("nКоличество байтов в секторе       - %d"
                "nКоличество секторов в кластере    - %d"
                "nЗарезервировано секторов          - %d"
                "nКоличество копий FAT              - %d"
                "nМакс. количество файлов в корневом каталоге - %d"
                "nОбщее количество секторов на диске          - %d"
                "nБайт-описатель среды              - %x"
                "nКоличество секторов в FAT         - %d",
                boot_rec->bpb.sectsize,
                boot_rec->bpb.clustsize,
                boot_rec->bpb.ressecs,
                boot_rec->bpb.fatcnt,
                boot_rec->bpb.rootsize,
                boot_rec->bpb.totsecs,
                (unsigned char)boot_rec->bpb.media,
                boot_rec->bpb.fatsize);
 
  printf("nnИнформация из расширения BPB:n");
 
  printf("nСекторов на дорожке               - %d"
                "nКоличество головок                - %d"
                "nСкрытых секторов для диска < 32M  - %d"
                "nСкрытых секторов для диска >= 32M - %d"
                "nВсего секторов на диске           - %u",
                boot_rec->bpb.seccnt,
                boot_rec->bpb.headcnt,
                boot_rec->bpb.hiddensec_low,
                boot_rec->bpb.hiddensec_hi,
                boot_rec->bpb.totsecs);
 
// Освобождаем буфер
  free(boot_rec);
  
  system("pause");
  return 0;
}
Yandex
Объявления
03.09.2012, 19:20     Как правильно вставить код на ассемблере?
Ответ Создать тему
Опции темы

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