С + + с ассемблерных включениями

  • Автор темы Ponka
  • Дата начала
P

Ponka

#1
не знаю как организовывать работу .. и как писать ... (или под DOS, под Win32)
Задача:
программирования прямого доступа к памяти в защищенном режиме
Рекомундации:
1. использовать MASM
2. викоистовуваты ассемблерные включения в C + + где поддерживаются API
помогите пожалуйста с задачей.
 

lazybiz

Well-known member
03.11.2010
1 339
0
#2
Тут тебе явно не Win32 нужен.
"викоистовуваты" - это что?
Давай конкретней. Что есть. Чего нет. И что надо.
 

lazybiz

Well-known member
03.11.2010
1 339
0
#4
Чтобы перейти в защищенный режим, нужно:
C++:
mov eax, cr0
or al, 1
mov cr0, eax
и сразу прыгнуть по селектору (объявленному GDT) и смещению на 32-битный код (16-битный PM режим я не рассматриваю).
При этом, сначала нужно загрузить в регистр Глобальной Таблицы Дескрипторов (она же GDT) физический адрес этой таблицы. И не забыть про IDT.
А вообще тут геморроя не оберешься. Проще ублажить препода, т.к. тебе даже за деньги тут это делать вряд ли кто-то будет...
 
P

Ponka

#5
нужна программа на С + + с ассемблерными вставками, которая будет выполнять прямой доступ к памяти (простой пример: выделение 2Кб для стека или сохранения определенного числа в определенную ячейку памяти) в защищенном режиме.
 

lazybiz

Well-known member
03.11.2010
1 339
0
#6
прямой доступ к памяти (простой пример: выделение 2Кб для стека или сохранения определенного числа в определенную ячейку памяти)
Прямой Доступ к Памяти - DMA - осуществляет обмен данными между устройством и основной памятью.

Какой стек!? Какая ячейка памяти!?? Сформулируйте вопрос понятным языком.
Вот тут про DMA почитайте: http://ru.wikipedia.org/wiki/DMA
 
P

Ponka

#7
тебе даже за деньги тут это делать вряд ли кто-то будет...
если да то как сделать вставку в С + +

#include "stdafx.h"
#include <iostream>
#include <fstream>

using namespace std;

int main()
{
_asm{
mov bx,offset GDT + 8 ; Нулевой дескриптор устанавливать
; не будем - всё равно он не
; используется.

xor eax,eax ; EAX = 0
mov edx,eax ; EDX = 0

push cs
pop ax ; AX = CS = сегментный адрес текущего
; сегмента кода.

shl eax,4 ; EAX = физический адрес начала сегмента кода.
; Эта программа, работая в среде операционной системы
; режима реальных адресов (подразумевается, что это -
; MS-DOS) уже имеет в IP смещение относительно
; текущего сегмента кода. Мы определим дескриптор
; кода для защищённого режима с таким же адресом
; сегмента кода, чтобы при переходе через команду
; дальнего перехода фактически переход произошёл
; на следующую команду.

mov dx,1024 ; Предел сегмента кода может быть любым,
; лишь бы он покрывал весь реально
; существующий код.

mov cl,10011000b ; Права доступа сегмента кода (P = 1,
; DPL = 00b, S = 1, тип = 100b, A = 0)

call set_descriptor ; Конструируем дескриптор кода.

lea dx,Stack_seg_start ; EDX = DX = начало стека (см. саму
; метку).

add eax,edx ; EAX уже содержит адрес начала сегмента
; кода, сегмент стека начнётся с последней
; метки программы Stack_seg_start.

mov dx,1024 ; Предел стека. Также любой (в данном
; примере), лишь бы его было достаточно.

mov cl,10010110b ; Права доступа дескриптора сегмента
; стека (P = 1, DPL = 00b, S = 1,
; тип = 011b, A = 0).

call set_descriptor ; Конструируем дескриптор стека.

xor eax,eax ; EAX = 0
mov ax,ds
shl eax,4 ; EAX = физический адрес начала сегмента данных.
xor ecx,ecx ; ECX = 0
lea cx,PMode_data_start ; ECX = CX
add eax,ecx ; ECX = физический адрес начала сегмента
; данных.

lea dx,PMode_data_end
sub dx,cx ; DX = PMode_data_end - PMode_data_start (это
; размер сегмента данных, в данном примере
; он равен 26 байтам). Этот размер мы и
; будем использовать как предел.

mov cl,10010010b ; Права доступа сегмента данных (P = 1,
; DPL = 00b, S = 1, тип = 001, A = 0).

call set_descriptor ; Конструируем дескриптор данных.

mov eax,0b8000h ; Физический адрес начала сегмента
; видеопамяти для цветного текстового
; режима 80 символов, 25 строк
; (используется по умолчанию в MS-DOS).

mov edx,4000 ; Размер сегмента видеопамяти (80*25*2 = 4000).
mov cl,10010010b ; Права доступа - как сегмент данных
call set_descriptor ; Конструируем дескриптор сегмента
; видеопамяти.

; Устанавливаем GDTR:

xor eax,eax ; EAX = 0
mov edx,eax ; EDX = 0

mov ax,ds
shl eax,4 ; EAX = физический адрес начала сегмента данных.
lea dx,GDT
add eax,edx ; EAX = физический адрес GDT
mov GDT_adr,eax ; Записываем его в поле адреса образа GDTR.

mov dx,39 ; Предел GDT = 8 * (1 + 4) - 1
mov GDT_lim,dx ; Записываем его в поле предела образа GDTR.

cli ; Запрещаем прерывания. Для того, чтобы прерывания
; работали в защищённом режиме их нужно специально
; определять, что в данном примере не делается.

lgdt GDTR ; Загружаем образ GDTR в сам регистр GDTR.

; Переходим в защищённый режим:

mov eax,cr0
or al,1
mov cr0,eax

db 0eah
dw P_Mode_entry
dw Code_selector



}
system("pause");
return 0;}


1>asm.cpp
1>c:\documents and settings\admin\мои документы\visual studio 2005\projects\asm\asm\asm.cpp(10) : error C2443: operand size conflict
1>c:\documents and settings\admin\мои документы\visual studio 2005\projects\asm\asm\asm.cpp(97) : error C2443: operand size conflict
1>c:\documents and settings\admin\мои документы\visual studio 2005\projects\asm\asm\asm.cpp(111) : error C2400: inline assembler syntax error in 'opcode'; found 'constant'
1>c:\documents and settings\admin\мои документы\visual studio 2005\projects\asm\asm\asm.cpp(112) : error C2400: inline assembler syntax error in 'opcode'; found 'P_Mode_entry'
1>c:\documents and settings\admin\мои документы\visual studio 2005\projects\asm\asm\asm.cpp(113) : error C2400: inline assembler syntax error in 'opcode'; found 'Code_selector'
 

lazybiz

Well-known member
03.11.2010
1 339
0
#8
как сделать вставку в С + +
Сделать вставку в С++ можно например вот так:
__asm {
mov eax, ebx
}

Выдает потому, что вот здесь:
ты хочешь в 16-битный регистр запихнуть 32-битное значение.

И еще мне интересно, как ты в Visual Studio хочешь скомпилировать программу, которая будет переходить в защищенный режим? Windows уже в защищенном работает и Visual Studio компилирует программы только для защищенного режима. Ты не сможешь, опять же, из Visual Studio скомпилировать программу для DOS, т.е. для реального режима.
 

lazybiz

Well-known member
03.11.2010
1 339
0
#9
У тебя же даже в сообщении написано:
...
; Эта программа, работая в среде операционной системы
; режима реальных адресов (подразумевается, что это -
; MS-DOS)...
...
 
D

dreamer

#11
Если я не ошибаюсь, вдобавок ко всему этому нужно будет комбинировать 16-ти и 32-битный код. Плюс, Ponka, Вы, полагаю, не дочитали http://sasm.narod.ru/docs/pm/pm_in/chap_9.htm (Вы ведь отсюда взяли код для перехода в PM?): после перехода нужно выполнить far jump на сегмент кода со смещением точки входа (т.е. в оригинале - P_Mode_entry).

Вам точно задавали именно такое задание? ;)
 

lazybiz

Well-known member
03.11.2010
1 339
0
#12
Ты не ошибаешься, поэтому я и сказал про бесконечный геморрой. Даже для знающего человека это довольно сложная задача, куда уж там обычным смертным...