Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: Изменение байтов в dword'е.  (Прочитано 29652 раз)
0 Пользователей и 1 Гость смотрят эту тему.
0xfadec0de
Интересующийся

ru
Offline Offline

« : 22-06-2009 21:28 » 

Всем доброго времени суток. Я совсем недавно начал заниматься С++ и уменя возник
вопрос как получить доступ к байтам дворда. Под доступом я имею ввиду не использование масок, а что то вроде этого:

Например у нас есть
dword dw = 0x77778899;
а мне нужно  получить доступ к 0x88 и изменить ,допустим, на 0xCC.
Возможно ли это сделать  без шаманства  с

void *tovoid; unsigned char *tobyte;
tovoid = pdword; tobyte = tovoid;

Возможно может существует штука наподобии std::bitset.

plzz ...
 
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 23-06-2009 03:17 » 

Код:
unsigned long dw;
unsigned char b0, b1, b2, b3;

b0 = dw & 255;
b1 = (dw >> 8) & 255;
b2 = (dw >> 16) & 255;
b3 = dw >> 24;
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #2 : 23-06-2009 03:59 » 

Код:
struct DWORD_STRUCT
{
  union
  {
     DWORD dw;
     char  arry[sizeof(DWORD)];
     struct
     {
         unsigned  b0  : 8;
         unsigned  b1  : 8;
         unsigned  b2  : 8;
         unsigned  b3  : 8;
     };
     struct
     {
         unsigned  bit0  : 1;
         unsigned  bit1  : 1;
         unsigned  bit2  : 1;
         ...
         unsigned  bit31 : 1;
     };

  };
};
Записан

while (8==8)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 23-06-2009 05:04 » 

sss, тип DWORD не стандартный — это только MS. Для остальных положен unsigned long. Потом, как у этой структуры с поддержкой разного порядка байт?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #4 : 23-06-2009 05:24 » 

RXL, какой вопрос, такой и ответ... А что, твой код сработает да?
Записан

while (8==8)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 23-06-2009 06:00 » 

sss, работает Улыбаюсь У меня не структура обрабатывается, а биты в dw.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #6 : 23-06-2009 06:45 » 

Не понял, номера байтов правильны в обоих случаях?
Записан

while (8==8)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 23-06-2009 06:59 » 

а структура красивше

Offtopic:

в паскале для этого есть record с case
Поставлю в угол.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
0xfadec0de
Интересующийся

ru
Offline Offline

« Ответ #8 : 23-06-2009 07:29 » 


Всем спасибо за ответы.
RXL,  Мы в таком случае, как я понял, получим в и b0...1 значения байтов дворда. А как сделать чтобы изменить это значение в самом дворде, что бы  у нас изменилось значение с dw = 0x77778899  на
dw = 0x7777СС99;

 Как произвести адресацию определенного байта в дворде?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #9 : 23-06-2009 07:41 » 

0xfadec0de,
Код:
DWORD dwd;

((BYTE*)&dwd)[0]
((BYTE*)&dwd)[1]
((BYTE*)&dwd)[2]
((BYTE*)&dwd)[3]


(ну, не забывать только Ромины замечания Ага )
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #10 : 23-06-2009 07:47 » 

А как сделать чтобы изменить это значение в самом дворде, что бы  у нас изменилось значение с dw = 0x77778899  на
dw = 0x7777СС99;

0xfadec0de, ну ты даёшь!

А как изменить 584 на 594? Ага Совсем заучился?

Цитата
Как произвести адресацию определенного байта в дворде?

По смещению.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
sss
Специалист

ru
Offline Offline

« Ответ #11 : 23-06-2009 08:34 » 

Код:
struct DWORD_STRUCT
{
  union
  {
     DWORD dw;
     char  arry[sizeof(DWORD)];
     struct
     {
         unsigned  b0  : 8;
         unsigned  b1  : 8;
         unsigned  b2  : 8;
         unsigned  b3  : 8;
     };
     struct
     {
         unsigned  bit0  : 1;
         unsigned  bit1  : 1;
         ...
         unsigned  bit31  : 1;
     };

  };
  swap()
  {
    DWORD_STRUCT t;
    t.dw = 1;
    if ( t.bit0 != 1)
    {
      b3 ^= b0;
      b0 ^= b3;
      b1 ^= b2;
      b2 ^= b1;
      b1 ^= b2;
    }
  };
};

Код:
DWORD_STRUCT dt.dw = 0x77778899;
dw.swap();
//RXL можно работать ???
dt.b1 = 0xCC;
dw.swap();
Записан

while (8==8)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 23-06-2009 08:52 » 

sss, да черт его поймет... Сомневаюсь. Это же битовая цепочка в памяти - как там она располагается по стандарту... А целое число обрабатывается везде одинаково.

Гарантированно работать будет:
Код:
dw = (dw & 0xffff00ff) | (0xcc << 8);
« Последнее редактирование: 23-06-2009 08:54 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
sss
Специалист

ru
Offline Offline

« Ответ #13 : 23-06-2009 09:00 » 

RXL, не будет! Если младший байт по старшему адресу, почему не ?

Код:
dw = (dw & 0xffff00ff) | (0xcc000000 >> 8);

А мой код тестирует, преобразует если необходимо к своему формату, изменяет, а затем возвращает формат на место.
« Последнее редактирование: 23-06-2009 09:02 от sss » Записан

while (8==8)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #14 : 23-06-2009 09:00 » 

может вставить тест, который пнёт, если что ? )

Код:
{
//где то один раз
DWORD dwd=0x11223344;
if(sizeof(DWORD)!=4)trhow 0;
if(0+(BYTE*)&dwd !=0x44)trhow 0;
if(1+(BYTE*)&dwd !=0x33)trhow 0;
if(2+(BYTE*)&dwd !=0x22)trhow 0;
if(3+(BYTE*)&dwd !=0x11)trhow 0;
}
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 23-06-2009 09:01 » 

Насколько я знаю, меняться может позиция байт.  От старшего к младшему или от младшего к старшему.
Например:

FA C0 78 EF  <->  EF 78 C0 FA

А вот про биты... Не слышал.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
sss
Специалист

ru
Offline Offline

« Ответ #16 : 23-06-2009 09:03 » 

Джон, биты не меняются.

Алексей1153++ - посмотри внимательней на мой код...
Записан

while (8==8)
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 23-06-2009 09:04 » 

Мне тоже так кажется. Иначе операции смещения << >> не имели бы смысла.

ps Вернее смысл они бы имели, но вот результат был бы неоднозначным.

зы зы На практике пользуюсь способом предложенным RXL
« Последнее редактирование: 23-06-2009 09:06 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #18 : 23-06-2009 09:12 » 

А вобще-то парни... "Ну вы блин даёте" (с) так не проще будет?:

dw = 0x77778899;
dw += (0x7777СС99-dw);

А ещё проще:

dw = 0x77778899;
dw = 0x7777СС99;

Улыбаюсь)
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #19 : 23-06-2009 09:37 » 

sss, я про тест встроенного типа
Записан

0xfadec0de
Интересующийся

ru
Offline Offline

« Ответ #20 : 23-06-2009 10:24 » 

Всем спасиба, в общем я сделал так (для примера с 0x77778899 - > 0x7777СС99)

unsigned long fff (unsigned long dw)
{
     asm  MOV  AH , 0xCC
}

эммм как я понял лучьше для адресации использовать асм :]
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #21 : 23-06-2009 10:27 » 

0xfadec0de, ты всё неправильно понял, да и код твой сделает не то, что ты хотел )
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #22 : 23-06-2009 10:35 » 

RXL, не будет! Если младший байт по старшему адресу, почему не ?

Код:
dw = (dw & 0xffff00ff) | (0xcc000000 >> 8);

А мой код тестирует, преобразует если необходимо к своему формату, изменяет, а затем возвращает формат на место.
Не знаю на счет твоего кода - не проверял. Мой 100% работает на любом порядке байт: порядок меняется в памяти, а в регистрах он вообще не имеет смысла.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
0xfadec0de
Интересующийся

ru
Offline Offline

« Ответ #23 : 23-06-2009 10:47 » 

0xfadec0de, ты всё неправильно понял, да и код твой сделает не то, что ты хотел )
Разве код не работает конкретно к примеру (0x77778899 - > 0x7777СС99)
Что я делаю  не првельно   С ума сойти...
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #24 : 23-06-2009 11:04 » 

0xfadec0de, ну, скажем так, использование ассемблера тут роли не играет (хотя, ты привязал программу к типу процессора, пусть даже и очень распространённому)

кроме того, код засунет 0xcc в регистр, а тебе нужна переменная
Записан

0xfadec0de
Интересующийся

ru
Offline Offline

« Ответ #25 : 23-06-2009 11:31 » 

В регистре EAX после отработки fff будет  0x7777СС99. Переменную получим так например

unsigned long z  =  0x7777СС99;
unsigned long z  = fff(z);

Хотя это всеаки очень бредовый  способ.
Самы оптимальный это
x = (x & 0xffff00ff) | (0xcc << 8 )
Как подсказал RXL.
Записан
yanart
Гость
« Ответ #26 : 28-08-2009 07:21 » 

Всем доброго времени суток. Я совсем недавно начал заниматься С++ и уменя возник
вопрос как получить доступ к байтам дворда. Под доступом я имею ввиду не использование масок, а что то вроде этого:

Например у нас есть
dword dw = 0x77778899;
а мне нужно  получить доступ к 0x88 и изменить ,допустим, на 0xCC.
Возможно ли это сделать  без шаманства  с

void *tovoid; unsigned char *tobyte;
tovoid = pdword; tobyte = tovoid;

Возможно может существует штука наподобии std::bitset.

plzz ...
 

Все очень просто

union
{
  unsigned long dw;
  unsigned char b[4];
}u;

void main()
{
   u.dw = 0x77778899;
   u.b[1]=0xCC;
}
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #27 : 28-08-2009 08:09 » 

yanart, зачем такой опасный способ, в посте sss #2 всё гораздо лучше сделано )

Мы тут смотрим, ты спамить и свой сайт рекламить пришёл. За это можно и наказать, учти
« Последнее редактирование: 28-08-2009 08:10 от Алексей1153++ » Записан

yanart
Гость
« Ответ #28 : 28-08-2009 09:02 » 

yanart, зачем такой опасный способ, в посте sss #2 всё гораздо лучше сделано )

Мы тут смотрим, ты спамить и свой сайт рекламить пришёл. За это можно и наказать, учти

1. Я просто показал человеку ответ на его вопрос.
2. Спам - это когда ответ не несет смысловой нагрузки.
3. А разве подписи запрещены?
4. А разве плохо, когда новички увидят бесплатные видеоматериалы на моем сайте?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #29 : 28-08-2009 09:15 » 

2. да
3. запрещена реклама в них
4. да
Записан

yanart
Гость
« Ответ #30 : 28-08-2009 09:53 » 

yanart, зачем такой опасный способ, в посте sss #2 всё гораздо лучше сделано )

Алексей1153++, если вы считате что код опасный, разверните свой ответ. Я в этом коде не вижу никакой опасности, даже если unsigned long будет 10 байт. Ведь сначало идут младшие байты числа, а нам надо поменять старший байт младщего слова. Зачем громоздить лишнего (пример исходник sss).

Считаю, если делать сдвигами - влияет на быстродействие, если асмом, то конечно вариант, но
не все знают ассемблер, мой вариант простой.

Уж, извините, если что не так.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #31 : 28-08-2009 10:00 » 

yanart,

1) развёртываю:

void main()
{
   u.dw = 0x77778899;
   u.b[111]=0xCC;    // вылет или попорченные данные программы
}

2)
Цитата
Считаю, если делать сдвигами - влияет на быстродействие
компилятор всё это превратит в прямые подстановки адресов байтов, и не будет рантайм сдвигов Улыбаюсь Работать будет мновенно

громоздкости у sss не вижу , вижу только правильное обращение с памятью

3)
Цитата
если асмом, то конечно вариант

абсолютно не вариант


« Последнее редактирование: 28-08-2009 10:02 от Алексей1153++ » Записан

yanart
Гость
« Ответ #32 : 28-08-2009 10:04 » 

yanart,

1) развёртываю:

void main()
{
   u.dw = 0x77778899;
   u.b[111]=0xCC;    // вылет или попорченные данные программы
}

2)
Цитата
Считаю, если делать сдвигами - влияет на быстродействие
компилятор всё это превратит в прямые подстановки адресов байтов, и не будет рантайм сдвигов Улыбаюсь Работать будет мновенно

громоздкости у sss не вижу , вижу только правильное обращение с памятью

3)
Цитата
если асмом, то конечно вариант

абсолютно не вариант


Извините, так тогда по вашему и со строками работать "опасный код"

char s[10];
s[111]='a';
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #33 : 28-08-2009 10:06 » 

yanart, для строк существуют:
1) спецклассы (std::string , CString)
2)
const char* s;
s="a";
+ функции работы со строками

3) ну и почитать книжки по с++ Ага

yanart, ты попробуй код sss, потом поделай действий  и посмотри в дизассемблере Улыбаюсь

Давай, если ты убираешь рекламу , мы просто будем считать тебя новичком, а не спамером ?
Записан

yanart
Гость
« Ответ #34 : 28-08-2009 10:22 » 

yanart, для строк существуют:
1) спецклассы (std::string , CString)
2)
const char* s;
s="a";
+ функции работы со строками

3) ну и почитать книжки по с++ Ага

yanart, ты попробуй код sss, потом поделай действий  и посмотри в дизассемблере Улыбаюсь

Давай, если ты убираешь рекламу , мы просто будем считать тебя новичком, а не спамером ?

Я её уже давно убрал! Я единственное не понимаю, почему такая агрессия на форуме, ну да была реклама, так как я не увидел, что нельзя рекламу в подписи делать, можно было в личку написать, я бы её убрал. Я ведь не ради наживы! Просто я сейчас создаю бесплатные видеоуроки по С++, ну и народу может было бы интересно, я со своего сайта ведь с этой рекламмы ни копейки не получу.

Написал код, сразу его обхаяли!

Ну вот скажи мне, какой идиот напишет в своей программе
u.b[111]=0xCC;
когда объявил массив из 4-ех элементов?

Ладно, согласен, для работы со строками есть классы, только не всегда ими хочется пользоваться.
А если не со строками
int A[10];
A[101]=666;

Какой класс посоветуете? Конечно можно написать свой, а то вдруг за пределы массива выскочу;) ведь так?
Записан
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #35 : 28-08-2009 10:23 » 

Алексей1153++, не, а кто мешает написать функции побайтовой работы с long?

Не вижу ничего плохого в массиве. Можно ещё:
Код:
union
{
   long value;
   struct
   {
      char first;
      char second;
      char third;
      char fourth;
   } bytes;
}
И следить за выравниванием.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #36 : 28-08-2009 10:32 » 

Ну вот скажи мне, какой идиот напишет в своей программе
u.b[111]=0xCC;
когда объявил массив из 4-ех элементов?
да любой, и не обязательно идиот. Раз класс это позволяет напрямую сделать - ошибка может случиться. А вот если бы ты сделал этот массив private , ябы ни слова не сказал Ага

Ладно, согласен, для работы со строками есть классы, только не всегда ими хочется пользоваться.
А если не со строками
int A[10];
A[101]=666;

Какой класс посоветуете? Конечно можно написать свой, а то вдруг за пределы массива выскочу;) ведь так?
да любой из названных + самописный

Dimka, дык, что угодно можно написать, лишь бы не делать явных грубых ошибок )

yanart, а насчёт агрессии - так это я с недосыпу. Ну и вообще, я очень агрессивный Отлично
Записан

Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #37 : 28-08-2009 12:10 » 

Алексей1153++, работа с двойным словом побайтово с целью именно доступа к байтам - это, имхо, в любом случае низкоуровневая работа, требующая внимательности и прямых рук. Поэтому можно делать как угодно, лишь бы метод был переносимым и надёжным с точки зрения компиляции правильного кода.

Кстати, у sss в примере был
Код:
char  arry[sizeof(DWORD)];
в структуре Ага (и это, к слову, лучше, чем arry[4])
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #38 : 28-08-2009 14:46 » 

ну это я не заметил -
char  arry[sizeof(DWORD)];


) Но поля всё таки безопаснее
Записан

yanart
Гость
« Ответ #39 : 28-08-2009 16:36 » 

Алексей1153++, работа с двойным словом побайтово с целью именно доступа к байтам - это, имхо, в любом случае низкоуровневая работа, требующая внимательности и прямых рук. Поэтому можно делать как угодно, лишь бы метод был переносимым и надёжным с точки зрения компиляции правильного кода.

Кстати, у sss в примере был
Код:
char  arry[sizeof(DWORD)];
в структуре Ага (и это, к слову, лучше, чем arry[4])

Согласен, но так как мы обращаемся к старшему байту младшего слова, это не существенно.
Записан
yanart
Гость
« Ответ #40 : 28-08-2009 16:40 » 

Алексей1153++, а как бы ты решил следующую задачу со своей МЕГАбезопасностью?

Переставить местами в строке первый и последний элементы. Интересно посмотреть Улыбаюсь

char s[]="Hello word";
...

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #41 : 28-08-2009 16:44 » 

фигня задача )
Код:
char s[]="Hello word";

int len=::strlen(s);
if(len)
{
   char c=s[0];
   s[0]=s[len-1];
   s[len-1]=c;
}

yanart, я ж к чему прицепился то ? Не из удовольствия, а справедливости ради: ты советуешь человеку public массив , вместо private массива+public методов. Только к этому, а так не на что обижаться
« Последнее редактирование: 28-08-2009 16:46 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #42 : 28-08-2009 16:47 » 

а про "со своей МЕГАбезопасностью? " зря язвишь - вот программы таких как ты хакеры и используют для распространения вирусов. Лучше я поманьячу с надёжностью, чем потом изза меня ограбят банк

а типом char[] я не пользуюсь, только const char* или CString. Последнее часто экономит время и силы Улыбаюсь
Записан

yanart
Гость
« Ответ #43 : 28-08-2009 16:49 » 

Задача то простая, не ну согласись, код опасный, за пределы можно вылезти Улыбаюсь

Ладно, предлагаю дружбу  Ага
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


WWW
« Ответ #44 : 28-08-2009 16:51 » 

да никто и не ссорился, заметь )

Насчёт опасного кода - так это же не член класса, поэтому и опасно ))
Записан

Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines