Написал тут одну прогу на Delphi, посмотрел на размер и ужаснулся - 600кб. Плюнул, решил сделать на ассемблере. Программа считывает с сайта провайдера данные о траффике пользователя за текущий месяц и считает его стоимость. Проблема в части расчета стоимости. Вот этот кусок кода: Код (Text): fldz fstp cost xor ecx,ecx mov esi, @ ad mov edi, @ ap @@: mov eax, [esi+4*ecx] mov f_adk, eax ;ad[k] mov eax, [edi+4*ecx] mov f_apk, eax ;ap[k] .if ecx==0 mov f_tmp, 50 fild f_tmp fst f_d ;d:=50 .else dec ecx mov ebx, [esi+4*ecx] ;ad[k-1] inc ecx mov eax, f_adk mov f_tmp,ebx fld f_adk fsub f_tmp fld1 fsub fst f_d ;d:=ad[k]-ad[k-1]-1 .endif ;if t>=ad[k] fld f_t fild f_adk fcom fstsw ax sahf .if CARRY? fld f_d ;<---- error ST(0) = -NAN fld f_apk fmul fld cost fadd fst cost ;c:=c+d*ap[k] .else ;if t>(ad[k]-d) fld f_d fld f_adk fsub fld f_t fcom fstsw ax sahf .if !CARRY? ;c:=c+(t-ad[k]+d)*ap[k] fld f_d fld f_adk fadd fld f_t fsub fld f_apk fmul fld cost fadd fst cost .endif .endif inc ecx cmp ecx, 7 jne @B Переменные заданы так: f_t REAL4 ? f_d REAL4 ? f_tmp REAL4 ? f_apk REAL4 ? f_adk REAL4 ? cost REAL4 ? ap REAL4 1.0, 1.8, 1.5, 1.3, 1.2, 1.1, 1.0 ad dd 50, 100, 300, 500, 1024, 2048, 5120 Ошибка возникает в время второго исполнения цикла при fld f_d в ST(0) оказывается -NAN, хотя f_d=42440000h (или 49,0). Второй день мучаю отладчик Вот работающий код на Delpi: Код (Text): ap: array [0..6] of real = (1,1.8,1.5,1.3,1.2,1.1,1); ad: array [0..6] of integer = (50,100,300,500,1024,2048,5120); c := 0; for k:=0 to 6 do begin if k=0 then d:=50 else d:=ad[k]-ad[k-1]-1; if t>=ad[k] then c:=c+d*ap[k] else if t>(ad[k]-d) then c:=c+(t-ad[k]+d)*ap[k]; end;
Замени все fld f_adk на fild f_adk Или измени копирование ad в f_adk (fild ad + fstp f_adk), но тогда не забудь исправить одну затесавшуюся fild f_adk
Прошу прощения, не ту строчку запостил Должно быть вот так: ad REAL4 50.0, 100.0, 300.0, 500.0, 1024.0, 2048.0, 5120.0 Соответственно все операции с fld.
Честно говоря лень в твоей писанине разбираться Достаточно того что у тебя вместо fstp везде fst стоят - переполнение стека FPU гарантировано. Да и бесконечные загрузки\выгрузки в память тут совершенно ни к чему Одним словом проще заново переписать. Но сначала стоит разобраться с формулами, чтобы упростить\унифицировать вычисления. Путем элементарных подстановок приходим к выводу, что величина d тут вообще не нужна и все вычисления сводятся к Код (Text): c = c+(b-e)*ap[k], где e = ad[k-1]+1, начальное значение = 0 b = ad[k] при t >= ad[k] t при e <= t < ad[k] 0 при t < e Если расчитывать на процы не ниже P6 family (PII,PIII), то все легко и просто реализуется на fcomi и fcmovXX: Код (Text): lea edi,[ap] lea esi,[ad] fld f_t ;f_t fldz ;c fldz ;e=ad[k-1]+1 @@: fild dword [esi+ecx*4] ;ad[k], для целых fild, для REAL4 fld fld st3 ;b=f_t fcomi st0,st2 ;сравниваем f_t и e fcmovb st0,st2 ;f_t < e -> b=e fcomi st0,st1 ;сравниваем f_t и ad[k] fcmovnb st0,st1 ;f_t >= ad[k] -> b=ad[k] fsub st0,st2 ;b-e fmul dword [edi+ecx*4] ;(b-e)*ap[k] faddp st3,st0 ;c=c+(b-e)*ap[k] fld1 fadd ;новое значение е=ad[k]+1 fstp st1 ;выбрасываем предыдущее значение е inc ecx cmp ecx 7 jl @B fstp st0 ;выбрасываем e fstp c ;сохраняем c fstp st0 ;выбрасываем f_t
Sfinks На сайте Ms Rem есть туториал по минимизации размера экзешника на Delphi. Ваш пример должен уместиться в 5-6Кб.