Лора Батлер задаёт вопрос: кому в голову пришла идея возвращать основную (major) версию в младшем байте, а младшую (minor) версию - в старшем байте функции
GetVersion. Надо же делать наоборот: нужно возвращать основную версию в старшем байте и младшую версию в младшем байте, чтобы вы могли делать такое:
if ГипотетическаяУлучшеннаяGetVersion >= $030A then begin // версия минимум 3.10 end;Вместо этого сейчас основная версия возвращается в младшем байте, а младшая версия - в старшем байте, поэтому версия 3.10 возвращается как значение
$0A03, что приводит к таким ошибкам:
if GetVersion >= $0A03 then begin // неверная проверка на версию ≥ 3.10 end;Почему номер версии возвращается таким странным образом?
Мысленно перенеситесь назад во времени во времена MS-DOS.
MS-DOS имеет системный вызов Get Version и он возвращает версию операционной системы тем же способом (в обратном порядке - с основной версией в младшем байте и второстепенной версией в старшем байте).
Идея заключалась в том, что программы почти всегда будут проверять только основную (major) версию - потому что вам нужно проверять младшую (minor) версию только если вам нужно проверить на какую-либо функцию, добавленную во вспомогательной версии. Но, по определению, второстепенные версии не добавляют много функций (верно, ведь?), поэтому проверка на минорную версию должна быть очень редкой.
В ту эпоху программы писались на ассемблере, и именно эта деталь проливает свет на столь необычный формат номера версии.
На 8086 16-разрядный регистр
AX может рассматриваться как 16-разрядное значение или как два 8-разрядных значения. Если вы рассматриваете его как два 8-битных значения, то старший байт называется AH, а младший байт называется AL.Инструкции 8086 для сравнения значений в этих регистрах кодируются следующим образом:
| Инструкция | Машинный код |
|---|---|
CMP AL, $03 | 3C 03 |
CMP AH, $03 | 80 FC 03 |
Поскольку почти все будут сравнивать только основную версию - нам следует сделать эту проверку наиболее эффективной. Следовательно, нам нужно выбрать вариант с регистром
AL. Использование регистра AL (младшего байта) для хранения основной версии позволяет короче записывать проверки версий, чем если бы мы использовали регистр AH.Мы только что сэкономили целый байт!
IBM PC поставлялся в двух конфигурациях памяти: с 16 Кб и 64 Кб. Если вы выложили бо́льшие деньги за 64-килобайтную версию, то этот один байт составляет 0.0015% от общего объёма памяти. Если мы промасштабируем до современной системы с 8 Гб ОЗУ, то выбор такого формата возврата номера версии экономит нам 128 Кб.
Windows же унаследовала схему нумерации версий из MS-DOS, и поэтому функция
GetVersion возвращает основную и младшую версии в обратном порядке.
Не мог найти Вашу почту поэтому написал сюда.Помогите пожалуйста!
ОтветитьУдалитьНужно залить большую таблицу, около миллиона строк в БД Firebird 2.5
Пробую импортировать так:
procedure XlsToStringGrid(AGrid: TStringGrid; AXLSFile: string);
const
xlCellTypeLastCell = $0000000B;
var
XLApp, Sheet: OLEVariant;
RangeMatrix: Variant;
x, y, k, r: Integer;
begin
XLApp := CreateOleObject('Excel.Application');
try
xlapp.Visible := False;
XLApp.Workbooks.Open(AXLSFile);
Sheet := XLApp.Workbooks[ExtractFileName(AXLSFile)].WorkSheets[1];
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;
x := XLApp.ActiveCell.Row;
y := XLApp.ActiveCell.Column; AGrid.RowCount := x;
AGrid.ColCount := y;
{rcounts:=x;}
RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;
k := 1;
repeat
for r := 1 to y do AGrid.Cells[(r - 1), (k - 1)] := RangeMatrix[K, R];
Inc(k, 1);
AGrid.RowCount := k + 1;
until k > x;
RangeMatrix := Unassigned;
finally
if not VarIsEmpty(XLApp) then
begin
xlapp.application.screenupdating:=true;
xlapp.application.enableevents:=true;
xlapp.application.interactive:=true;
xlapp.application.displayalerts:=true;
XLApp.ActiveWorkBook.Close;
XLAPP := Unassigned;
Sheet := Unassigned;
end;
end;
end;
На строке RangeMatrix := XLApp.Range['A1', XLApp.Cells.Item[X, Y]].Value;
вылетает такая ошибка: EOleSysError Недостаточно памяти для завершения операции!
RAM 8 Gb на моем ПК, мониторил память и во время вылета было 4,4 Гб свободно.
Как побороть эту проблему?