Skalowanie obrazu bmp asembler

0

Witam,
mam do napisania program, który będzie skalował obraz w formacie BMP 24bpp. Wczytywanie pliku oraz skali ma być wykonywane w c, zaś sam proces zmniejszania obrazu jako zewnętrzna funkcja napisana w asemblerze intela x86. Próbowałem trochę sobie pomóc i napisałem ją w c, a potem zdekompilowałem używając objdump. Problem w tym, że po ponownej kompilacji już z funkcją w asemblerze dostaję segmentation fault przy uruchomieniu. Poniżej zamieszczam kod i prosze o pomoc.

 section .text

global shrinkbmp24

shrinkbmp24:


push   ebp
mov    ebp,esp
sub    esp,0x58
    ;float scale = (float)scale_num / (float)scale_den;
mov    eax,DWORD [ebp+0x10]
mov    edx,0x0
mov    DWORD [ebp-0x58],eax
mov    DWORD [ebp-0x54],edx
fild   QWORD [ebp-0x58]
fstp   DWORD [ebp-0x44]
fld    DWORD [ebp-0x44]
mov    eax,DWORD [ebp+0x14]
mov    edx,0x0
mov    DWORD [ebp-0x58],eax
mov    DWORD [ebp-0x54],edx
fild   QWORD [ebp-0x58]
fstp   DWORD [ebp-0x44]
fld    DWORD [ebp-0x44]
fdivrp st1,st0
fstp   DWORD [ebp-0x28]
    ;int newHeight = 0, newWidth, actWidth, tmpInt, actHeight = 0, offset = 0, actPadding, newPadding;
mov    DWORD [ebp-0x24],0x0
mov    DWORD [ebp-0x20],0x0
mov    DWORD [ebp-0x1c],0x0
    ;int padding_new = 0, padding_act = 0, cy, cx, cyNewWidthNewPadding, cyScaleActWidth3Scale;
mov    DWORD [ebp-0x38],0x0
mov    DWORD [ebp-0x34],0x0
    ;//mov eax, DWORD[esi+10]
    
    
    ;//i = 22 18 - 12, 22 - 25;
    
    ;offset = 54;
mov    DWORD [ebp-0x1c],0x36
    ;actWidth = 1366;
mov    DWORD [ebp-0x18],0x556
    ;newWidth = actWidth * scale;
fild   DWORD [ebp-0x18]
fmul   DWORD [ebp-0x28]
fnstcw WORD [ebp-0x46]
movzx  eax,WORD [ebp-0x46]
mov    ah,0xc
mov    WORD [ebp-0x48],ax
fldcw  WORD [ebp-0x48]
fistp  DWORD [ebp-0x14]
fldcw  WORD [ebp-0x46]
    ;actHeight = 768;
mov    DWORD [ebp-0x20],0x300
    ;newHeight = actHeight * scale;
fild   DWORD [ebp-0x20]
fmul   DWORD [ebp-0x28]
fldcw  WORD [ebp-0x48]
fistp  DWORD [ebp-0x24]
fldcw  WORD [ebp-0x46]
    ;actPadding = 4 - ((actWidth * 3) % 4);
mov    edx,DWORD [ebp-0x18]
mov    eax,edx
add    eax,eax
add    edx,eax
mov    eax,edx
sar    eax,0x1f
shr    eax,0x1e
add    edx,eax
and    edx,0x3
sub    edx,eax
mov    eax,edx
mov    edx,0x4
sub    edx,eax
mov    eax,edx
mov    DWORD [ebp-0x40],eax
    ;newPadding = 4 - ((newWidth * 3) % 4);
mov    edx,DWORD [ebp-0x14]
mov    eax,edx
add    eax,eax
add    edx,eax
mov    eax,edx
sar    eax,0x1f
shr    eax,0x1e
add    edx,eax
and    edx,0x3
sub    edx,eax
mov    eax,edx
mov    edx,0x4
sub    edx,eax
mov    eax,edx
mov    DWORD [ebp-0x3c],eax
    

    ;if(actPadding == 4)
cmp    DWORD [ebp-0x40],0x4
jne    afterActPadding
        ;actPadding = 0;
mov    DWORD [ebp-0x40],0x0
afterActPadding:    
    ;if(newPadding == 4)
cmp    DWORD [ebp-0x3c],0x4
jne    afterNewPadding
        ;newPadding = 0;
mov    DWORD [ebp-0x3c],0x0
afterNewPadding:
    ;cy = 0;
mov    DWORD [ebp-0x30],0x0
    ;do
    ;{

doCy:
        ;cx = 0;
mov    DWORD [ebp-0x2c],0x0
        
        ;cyNewWidthNewPadding = cy * (newWidth *3 + newPadding);
mov    edx,DWORD [ebp-0x14]
mov    eax,edx
add    eax,eax
add    edx,eax
mov    eax,DWORD [ebp-0x3c]
add    eax,edx
imul   eax,DWORD [ebp-0x30]
mov    DWORD [ebp-0x10],eax
        ;cyScaleActWidth3Scale = (int)(cy / scale) * (actWidth *3 + actPadding);
fild   DWORD [ebp-0x30]
fdiv   DWORD [ebp-0x28]
fldcw  WORD [ebp-0x48]
fistp  DWORD [ebp-0x4c]
fldcw  WORD [ebp-0x46]
mov    ecx,DWORD [ebp-0x4c]

mov    edx,DWORD [ebp-0x18]
mov    eax,edx
add    eax,eax
add    edx,eax
mov    eax,DWORD [ebp-0x40]
add    eax,edx
imul   eax,ecx
mov    DWORD [ebp-0xc],eax
        
        ;do
        ;{

doCx:
            ;int pixel = (cyNewWidthNewPadding + (cx*3));

mov    edx,DWORD [ebp-0x2c]
mov    eax,edx
add    eax,eax
add    edx,eax
mov    eax,DWORD [ebp-0x10]
add    eax,edx
mov    DWORD [ebp-0x8],eax
            ;int nearestMatch =  (cyScaleActWidth3Scale + ((int)(cx / scale) *3) );
fild   DWORD [ebp-0x2c]
fdiv   DWORD [ebp-0x28]
fldcw  WORD [ebp-0x48]
fistp  DWORD [ebp-0x4c]
fldcw  WORD [ebp-0x46]
mov    edx,DWORD [ebp-0x4c]
mov    eax,edx
add    eax,eax
add    edx,eax
mov    eax,DWORD [ebp-0xc]
add    eax,edx
mov    DWORD [ebp-0x4],eax
               
            ;newImage[offset + pixel   ] =  buffer[offset + nearestMatch ];
mov    edx,DWORD [ebp-0x1c]
mov    eax,DWORD [ebp-0x8]
add    eax,edx
mov    edx,eax
mov    eax,DWORD [ebp+0xc]
add    edx,eax
mov    ecx,DWORD [ebp-0x1c]
mov    eax,DWORD [ebp-0x4]
add    eax,ecx
mov    ecx,eax
mov    eax,DWORD [ebp+0x8]
add    eax,ecx
movzx  eax,BYTE [eax]
mov    BYTE [edx],al
            ;newImage[offset + pixel + 1] =  buffer[offset + nearestMatch + 1];
mov    edx,DWORD [ebp-0x1c]
mov    eax,DWORD [ebp-0x8]
add    eax,edx
lea    edx,[eax+0x1]
mov    eax,DWORD [ebp+0xc]
add    edx,eax
mov    ecx,DWORD [ebp-0x1c]
mov    eax,DWORD [ebp-0x4]
add    eax,ecx
lea    ecx,[eax+0x1]
mov    eax,DWORD [ebp+0x8]
add    eax,ecx
movzx  eax,BYTE [eax]
mov    BYTE [edx],al
            ;newImage[offset + pixel + 2 ] =  buffer[offset + nearestMatch + 2];
mov    edx,DWORD [ebp-0x1c]
mov    eax,DWORD [ebp-0x8]
add    eax,edx
lea    edx,[eax+0x2]
mov    eax,DWORD [ebp+0xc]
add    edx,eax
mov    ecx,DWORD [ebp-0x1c]
mov    eax,DWORD [ebp-0x4]
add    eax,ecx
lea    ecx,[eax+0x2]
mov    eax,DWORD [ebp+0x8]
add    eax,ecx
movzx  eax,BYTE [eax]
mov    BYTE [edx],al
            
            ;cx++;
add    DWORD [ebp-0x2c],0x1
        ;} while(cx < newWidth);
        mov eax, DWORD[ebp-0x14]
        
mov    eax,DWORD [ebp-0x2c]
cmp    eax,DWORD [ebp-0x14]
jl     doCx
        
        ;padding_new += newPadding;
mov    eax,DWORD [ebp-0x3c]
add    DWORD [ebp-0x38],eax
        ;padding_act += actPadding / scale;
fild   DWORD [ebp-0x34]
fild   DWORD [ebp-0x40]
fdiv   DWORD [ebp-0x28]
faddp  st1,st0
fldcw  WORD [ebp-0x48]
fistp  DWORD [ebp-0x34]
fldcw  WORD [ebp-0x46]
        ;cy++;
add    DWORD [ebp-0x30],0x1
    ;} while(cy < newHeight);
mov    eax,DWORD [ebp-0x30]
cmp    eax,DWORD [ebp-0x24]
jl     doCy
    
leave  
ret    
0

Próbowałem trochę sobie pomóc i napisałem ją w c, a potem zdekompilowałem używając objdump.

No i myślisz, że nie będzie widać?

Napisz do tego jaki to asembler, jaki OS, jak to kompilujesz, jak wywołujesz z C.
Jaki ma być algorytm tego skalowania.

1 użytkowników online, w tym zalogowanych: 0, gości: 1