Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RusFAQ.ru: Программирование на C / C++


Информационный Канал Subscribe.Ru


RusFAQ.ru: Программирование на C / C++

Выпуск № 505
от 17.05.2004, 16:50

Администратор:
Имя: Nick.Box
URL: Информационный ресурс
ICQ: 365124
[censored], [censored]
О рассылке:
Задано вопросов: 1615
Отправлено ответов: 3200
Активность: 198.1 %
[Задать вопрос >>][Регистрация эксперта >>]
[Поиск в базе][Обсудить на форуме]


 Список экспертов, ответы которых опубликованы в данном выпуске

Sedric
Статус: Начальный
Общий рейтинг: 130
[Подробней >>]
www
Статус: Начальный
Общий рейтинг: 140.74
[Подробней >>]
CrackLab
Статус: Доверительный
Общий рейтинг: 160
[Подробней >>]


 Краткий перечень вопросов

Вопрос № 1611. Здравствуйте, уважаемые! Объясните, пожалуста, начинающему программёру. Я делал функцию для обмена з... (ответов: 3)

Вопросов: 1, ответов: 3


 Вопрос № 1611

Здравствуйте, уважаемые!
Объясните, пожалуста, начинающему программёру.
Я делал функцию для обмена значениями, для разных типов
в первый раз написал следующий код:
void AsmSwap(void*a,void*b){
asm{
pushad
mov eax,[a]
mov ebx,[b]
mov [b],eax
mov [a],ebx
popad
}
}
Проверил ее и ничего не вышло. Посмотрел я значит под отладчиком и вот что увидел:
в регистры копируется не значения по адресу, а сам адрес и естественно, что снаружи это никак не отображается, т.е. ничего не меняется. Хоть пиши в квадратных скобках, хоть вообще без скобок - одинаково работает. Пришлось менять код, в этом все получилось
void AsmSwap(void*a,void*b){
asm{
pushad
mov ebx,b
mov eax,a
push [eax]
push [ebx]
pop [eax]
pop [ebx]
popad
}
}
Почему в первом примере не влияют квадратные скобки (Объясните, пожалуста, как для начинающего, попадробнее, если можно.)?
Если ответ - просто адреса можно указывать только через регистры, то будьте добры, объясните почему через регистры, или это просто догма.
Делал я в C++ Builder 5, gод виндоус 98. Хотя тоже происходит и в DOS'е в borland 3.1 (я проверял, правда там не работали popad, pushad пришлось без них - в ручную не захотелось сохранять все регистры).
Спасибо за вашу помощь.
С уважением, Алксандр.



Вопрос отправлен: 13.05.2004, 22:10
Отправитель: Alexander

[Следующий вопрос >>] [Список вопросов]

Отвечает Sedric

Доброе время суток, Alexander!
А зачем вы себе жизнь усложняете?
Пишите так:
asm{
push a
push b
pop a
pop b
}
И нет никакой мороки с адресами
P.S. Регистры можно сохранить

Ответ отправлен: 15.05.2004, 17:42
Отправитель: Sedric


Отвечает www

Доброе время суток, Alexander!
Это скорее вопрос по ассемблеру.
Исходя из правил ассемблера, которые распространяются и на ассемблер встроенный в C++ Builder 5, при модификации адресов (что ты и патаешся изобразить квадратными скобками) необходимо использовать регистр модификатор, тогда, например, операция mov [eax],ebx по адресу eax будет записано значение содержащее в ebx.
Если же записать mov [a],ebx это будет эквивалентно
mov a,ebx, то есть значение ebx запишется по адресу переменной -a-, которая сама является адресом по которому находится нужное значение.

Ответ отправлен: 14.05.2004, 19:35
Отправитель: www


Отвечает CrackLab

Добрый день, Alexander!
Сейчас постараюсь объяснить.
Когды ты вызываешь свою первую подпрограмму например так:
byte b = 0x30;
char c = 'A';
AsmSwap(&b, &c);
то параметры передаются функции AsmSwap через стек. В данном случае наши параметры - адреса, по которым непосредственно находятся наши байты 0x30 и 0x41.
Внутри функции инструкция mov eax,[a] кладет в eax не то, что ты ожидаешь. Ты думаешь что в eax кладется байт 0x30 (точнее следует ожидать что в eax окажутся 4 байта - 0x30 и три следующих в памяти), но это обман. Дело в том, что параметр а - указатель, поэтому для непосредственному доступу к данным, на которые указывает указатель тебе надо углубиться дважды: сначала инструкция mov eax, [a] получает в eax адрес, по которому хранится байт 0x30, а затем надо еще положить в регистр байт по адресу, который хранится в eax. Ты же в своем примере, меняешь просто в стеке адреса двух параметров, но эта часть стека, принадлежит процедуре AsmSwap - дня нее значения как будто действительно меняются, но для внешней программы - ничего не меняется. Тут трудно это все объяснить. Лучше тебе еще разобраться в отладчике. Вот посмотри исправленный вариант программы (для обмена двух однобайтовых данных разного типа):
void AsmSwap(void*a,void*b)
{
asm
{
pushad
mov eax,[a]
mov ebx,[b]
mov cl, byte ptr [eax]
mov dl, byte ptr [ebx]
mov byte ptr [ebx], cl
mov byte ptr [eax], dl
popad
}
}
И в отладчике посмотри что происходит.
В данной реализации, непосредственно в памяти данные (а не указатели) меняются местами. В этом случае надо чтобы данные были одного размера. Можно просто поменять адреса, на которые указывают указатели, а данные на самом деле останутся на своих адресах. Это можно сделать например так:
int i = 0x41; /* Объявим и прикрепим к непосредственным данным 2 указателя и еще объявим один промежуточный указатель нужный для обмена */
int *b;
b = &i;
char *c = "LaLaLa";
void *tmp = c; // Обмениваем адреса, на которые указывают указатели
c = (char *)b;
b = (int *)tmp;
Caption = c; // Теперь Caption = "A" а не "LaLaLa"
Ну вот вроде и все...

Ответ отправлен: 15.05.2004, 13:12
Отправитель: CrackLab



Форма отправки вопроса

Внимание!
Мы рекомендуем открывать рассылку в программе Internet Explorer 5.0+ или отправлять вопросы с сайта по адресу: http://rusfaq.ru/cgi-bin/Message.cgi.

(C) 2002-2003 Команда RusFAQ.ru.

 Персональные данные

Ваше имя:

Ваш e-mail:

Опубликовать мой e-mail в рассылке


 Вопрос и дополнение

Ваш вопрос:


Приложение (если необходимо):


Получить ответов:


 Выбор рассылки

Программисту
Assembler (24)
C / C++ (14)
Perl (3)
Builder / Delphi (17)
Pascal (19)
Basic / VBA (2)
Java / JavaScript (3)
PHP (11)
Криптография (7)
WinAPI (7)
Радиоэлектроника (5)
Пользователю
Windows 95/98/Me (36)
Windows NT/2000/XP (51)
"Железо" (28)
Поиск информации (15)
Администратору
Windows NT/2000/XP (24)
Linux / Unix (8)
Юристу
Гражданское право (10)
Семейное право (7)
Трудовое право (9)
КоАП (6)

Отправить вопрос всем экспертам выбранной рассылки.




Задать вопрос | Регистрация эксперта | Поиск в базе | Чат | Форумы | Новости
Проект экспертов RusFAQ.ru | Фотоальбом | Virus.RusFAQ.ru | Администрирование
Профессиональная WEB-Студия B.I.T.


Яндекс цитирования
© 2001-2004 Россия, Москва. Авторское право: Калашников О.А.

http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу


В избранное