четверг, 28 мая 2009 г.

Ассемблер и параметры

Иногда требуется передать в процедуру параметр. Конечно, можно использовать регистры, но это не всегда возможно. Тогда на помощь приходит стэк. Правда, сопряжено с небольшой проблемой: после входа в процедуру в стэк заносится адрес возврата, и если был передан параметр, то он оказывается "вторым". Безусловно, можно заниматься собиранием ханойских башен в попытках достать нужное, но есть способ проще.
Стэк позволяет обращаться к себе со смещением, т.е. не к верхнему элементу. Пример:

lea di, mas
push di
call my_proc

my_proc PROC
mov bp,sp
mov di, [bp+2]
......
mas объявлен как dw, поэтому смещение == 2.
bp был задействован в силу ограниченности использования указателя стэка sp

вторник, 26 мая 2009 г.

Спец. символы в строках на С

Иной раз нужно, а не вспоминается: если надо в строку С включить какие-то необычные символы, то используется сочетание с клавишей \
str = "\"";
если нужна кавычка в строке, например.

\b

Backspace

\f

Form feed/прогон страницы

\n

New line/новая строка

\r

Carriage return/возврат каретки

\t

Tab/табуляция

\'

Апостроф или одинарная кавычка

\"

Двойная кавычка

\\

Обратный слэш (\)

Иконка в трее

Приятной особенность приложения может служить иконка в трее. Баловаться не стоит, снабжая каждый программный продукт подобной. А вот если предполагается длительное время работы, то хорошим тоном будет являться сворачивать программу не на панель задач, где места зачастую нет, а в область трея. Не только удобно, но и определённый запоминающийся образ появится. А если ещё и меню прикрутить... сказка!
На winAPI делается примерно так:

NOTIFYICONDATA nid;

memset(&nid, 0, sizeof(nid));
nid.cbSize = sizeof(nid);
nid.hWnd = hwnd; // хэндл имеющегося окна
nid.uID = ICON_ID; // номер иконки (если у приложения их несколько, то разные номера)
static HINSTANCE hInstance = GetModuleHandle(NULL);
nid.hIcon = ::LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON2));
lstrcpyn(nid.szTip, "Название программы", sizeof(nid.szTip)/sizeof(nid.szTip[0]));
nid.uCallbackMessage = WM_ShellNote; //ранее в define описан макрос-номер
nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
BOOL bSuccess = Shell_NotifyIcon(NIM_ADD, &nid);

понедельник, 25 мая 2009 г.

Строки в С

Строка в С, да и в С++, зачастую определяется как массив из символов, статический или динамический. А заканчиваться такая строка должна нуль-символом \0. Все знают, но забывают. А когда работа идёт с заведомо квадратной матрицей, то так и тянет выделять память n*n, но нет! Надо делать исключительно так:

char** matr;
matr = new char*[n];
for (int i = 0; i
matr[i] = new char[n+1];
matr[i][n] = '\0';
}


Иначе проблем в деструкторе, который будет освобождать всё, пока нуль-символ случайно не встретит, будет много

воскресенье, 24 мая 2009 г.

пакеты PL/SQL

Если в каких-то процедурах языка PL/SQL надо динамически работать с таблицами (создавать новые, например), то компилятор начинает ругаться, говоря, что "чего-то не хватает".
Как решается такая проблема?
sql-запрос берётся в одинарные кавычки и вызывается как execute immediate.
Например:

CREATE or replace PACKAGE BODY rally is

procedure buildQueue is
begin
execute immediate 'create table queue (
x number NOT NULL ENABLE,
y number NOT NULL ENABLE,
);';
end;

end rally;