Отладка приложений

       

Ссылки на структуры и классы


Поскольку структуры и классы играют значительную роль в Windows-разработках, потратим некоторое время на обсуждение проблем доступа к соответствующей памяти. Хотя со структурами и классами удобно иметь дело на языках высокого уровня, на уровне языка ассемблера они, вообще говоря, не существуют. На языках высокого уровня структура и класс — это просто краткие способы указывать смещения в "блобе" памяти.

"Блоб" (Binary Large Object — BLOB). Во-первых, этим термином разработчики баз данных обозначают любой произвольный битовый блок, который следует сохранить в БД, например картинку или звуковой файл. Существенно, что BLOB является объектом, который не может быть интерпретирован средствами СУБД. Во-вторых, употребляется в значении глагола (to blob) и в этом случае переводится как "послать огромный e-mail", обычно в ответ на нанесенное серьезное оскорбление. Часто используется в качестве умеренной угрозы. Например: "If that program crashes again, I'm going to BLOB the core dump to you" (Если эта программа опять "грохнется", я тебе вышлю дамп ядра по мэйлу). См. Файл Жаргона (The Jargon File). -Ред.

Компиляторы, в основном, размещают память для пользовательских структур и классов так, как указано в спецификациях. Иногда компилятор дополняет поля заполнителями, чтобы сохранять их на естественных границах памяти, которые для CPU x86 кратны 4 или 8 байтам.

Ссылки на структуры и классы обозначаются регистром и смещением памяти. В структуре Mystruct, приведенной ниже, комментарии справа показывают смещение каждого элемента от начала структуры. За определением MyStruct расположены различные способы доступа к полям структуры.

typedef struct tag_MyStruct

{

DWORD dwFirst ; // 0-байтное смещение 

char szBuff[ 256 ] ; // 4-байтное смещение 

int iVal ; // 260-байтное смещение

} MyStruct , * PMyStruct ;

void FillStruct ( PMyStruct pSt ) 

{

char szName[] = "Pam\n" ;

_asm

{

MOV EAX , pSt // Поместить pSt в EAX.
Ниже используются прямые

 // смещения на языке ассемблера, чтобы показать, 

// на что они похожи в дизассемблере. 

// Встроенный ассемблер позволяет применять

 // нормальные ссылки формата <struct>.<field>. 

// С-код: pSt->dwFirst = 23 ;

 MOV DWORD PTR [EAX] , 17h.

 // С-код: pSt->iVal = 0x33 ; 

MOV DWORD PTR [EAX + 0104h] , 0x33

 // С-код: strcpy ( pSt->szBuff , szName ) ; 

LEA ECX , szName // Поместить szName в стек.

 PUSH ECX .

LEA ECX , [EAX + 4] //. Получить доступ к полю szBuff.

 PUSH ECX 

CALL strcpy

ADD ESP ,8 // strcpy есть _cdecl функция.

// С-код: pSt->szBuff[ 1 ] = 'A' ; 

MOV BYTE PTR [EAX + 5] , 41h

 // С-код: printf ( pSt->szBuff ) ;

MOV EAX , pSt // Получить pSt обратно. EAX был разрушен

// при обращении к strcpy. 

LEA ECX , [EAX + 4]

 PUSH ECX

CALL DWORD PTR [printf]

ADD ESP , 4 // printf есть _cdecl-функция.

 } 

 }



Содержание раздела