Лора Батлер задаёт вопрос: кому в голову пришла идея возвращать основную (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 Гб свободно.
Как побороть эту проблему?