Вот когда пишешь эмулятор, очень много загвоздок. Например, составил две структуры: Для i80x86: Код (Text): typedef struct { union { struct { union { struct { char al; char ah; }; short ax; long eax; }; union { struct { char cl; char ch; }; short cx; long ecx; }; union { struct { char dl; char dh; }; short dx; long edx; }; union { struct { char bl; char bh; }; short bx; long ebx; }; union { short sp; long esp; }; union { short bp; long ebp; }; union { short si; long esi; }; union { short di; long edi; }; }; char r08[16]; short r16[8]; long r32[8]; }; union { char fl; short fx; long efx; }; union { short ip; long eip; }; short es; short cs; short ss; short ds; short fs; short gs; } X86REGS; и для i8080 / Z80: Код (Text): typedef union { struct { BYTE r8[8]; struct { BYTE r8[8]; } ex; }; struct { WORD r16[4]; struct { BYTE r16[4]; } ex; BYTE ptr[2]; }; struct { BYTE cl; BYTE ch; BYTE dl; BYTE dh; BYTE bl; BYTE bh; BYTE al; BYTE fl; struct { BYTE cl; BYTE ch; BYTE dl; BYTE dh; BYTE bl; BYTE bh; BYTE al; BYTE fl; } ex; BYTE ixl; BYTE ixh; BYTE iyl; BYTE iyh; WORD ip; BYTE i; BYTE r; }; struct { WORD cx; WORD dx; WORD bx; WORD psw; struct { WORD cx; WORD dx; WORD bx; WORD psw; } ex; WORD ix; WORD iy; WORD sp; WORD ip; WORD ir; __int64 regs; __int64 regx; __int64 ptrs; __int64 cnts; __int64 tacts; }; } X80REGS; Всё хорошо. А вот как можно память описать для стека например? Если описать как Код (Text): typedef struct { union { char Char[65537]; int Int[65536]; ... то реальное выравнивание Int будет кратно двум. Тогда как мне надо объяснить компилятору так, чтобы всюду не применять записи, типо *(int*)(Char + addr) а просто писать Int[addr] т.к. компилятор всё дополнит до Int[addr] как *(int*)(Char + addr * sizeof(int)) а мне это не нужно... Существует ли решение подобной задачи? Спасибо!
как там у вас с пультом для управления дверями и гвоздями в кинескопе? вроде как ошибка тут, хотя я совсем не понял чего вы мудрите нынче. способов есть. вы конкретный пример приведите. или макросы юзайте
Просто так не отделаться уже по той причине, что при обращении к WORD по адресу (индексу) 0xffff, нужно будет обратиться к байту по адресу 0.
Если правильно понял, нужно поставить выравнивание на структуру: Для MSVC __declspec(align(n)) для GCC __attribute__ ((aligned (n)))
никак! как 11 лет назад задумал, а лет 5 назад с другом обсуждал, так и всё в теории осталось... ошибки нет. на макросах был построен позапрошлый эмулятор. прошлый - чисто в _asm {...}, а нынче хочу всю мощь Си задействовать, если получится... само собою. контроль будет или тупое эхо-зеркало. Спасибо! проверю этот способ...
Paguo_86PK А вот здесь можно подробнее? int Int[65536]; - насколько я знаю выделит памяти нам 65536 * sizeof(int) байт, в то время как нам нужно всего 65536 (65536 + 1, если хотим обращаться к массиву слов) байт. Или правила в c++ уже поменялись?
Всё равно ведь нужна проверка на последний байт, не проще ли написать класс для Int и переопределить operator[] или в самом классе Stack написать функции доступа к байтам и словам. И align тут непричём, индексирование всё равно будет addr * sizeof(int).
Почему непоставленную? О_о я написал же: у меня три собственныхх эмулятора имеется: один - 8086 (си+макросы), и два - 8080 (си+макросы и си _asm)
Начал изучать AngelScript и сильно споткнулся на том, что никакого практического опыта в программировании на Си++ не имею. Код (Text): class _Screen: // Объявляем класс "Экран" public RefC { // счётчик обращений private: // Скрытые HDC hDC; // Указатель контекста DeskTop HPEN hPen; // Контекст пера HBRUSH hBrush; // Контекст кисти int nPenCounter; // Счётчик перьев int nBrushCounter; // Счётчик кистей public: // Доступные _Screen() { // Конструктор класса hDC = GetDC(NULL); // Инициация контекста экрана hPen = NULL; // Отчищение пера hBrush = NULL; // Отчищение кисти nPenCounter = 0; // Обнуление счётчика перьев nBrushCounter = 0; // Обнуление счётчика кистей }; ~_Screen() { // Деструктор класса ReleaseDC(NULL, hDC); // Освободить контекст DeleteObject(hPen); // Удалить перо DeleteObject(hBrush); // Удалить кисть }; // Как здесь правильно объявить? Ошибку компилятор выдаёт pen void(int color) { // Ставим новый цвет кисти ++ nPenCounter; // Инкремент счётчика изменений DeleteObject(SelectObject(hDC, hPen = CreatePen(PS_SOLID, 1, color)); }; pen int() { // Возвращаем число изменений кисти int n = nPenCounter; nPenCounter = 0; return n; }; }; Короче, ума не приложу, как в классе объявить, чтобы работал код: Код (Text): _Screen Scr; // Создаём экран Scr.pen = 0xFFCCAA; // Должна вызваться функция инкремента счётчика и смены цвета if(Scr.pen) ... // Кисть изменилась 1 раз, возвращенно функцией сброса счётчика Вообще опыта нет, а с ним - и идей, как объяснить компилятору что я затеял. Спасибо за помощь!