Are the 3 pointed lines in the source code redundant?

0

The following program detects an image on the basis of histogram and mode calculation.

SECTION .data
histogram_buffer: times 1024 db 0 ; 256 * 4
SECTION .text
global food

food:
    push ebp
    mov ebp,esp
    push esi
    push ecx
    push edx
    push ebx
    push edi
    mov esi,[ebp+8]; 1st function parameter. save address of input_bitmap in esi
    mov eax,[esi+18]; collect the width of the image 
    cmp eax,200 ; test if the width is 200
    jne food_error_width ; check for correct width
    mov eax,[esi+22]; obtain the height
    cmp eax,200 ; test if the height is 200
    jg food_error_height ; check for correct height 
    mov ax,word [esi+28]; obtain bit-depth of the image
    cmp ax,24 ; check it the image is 24-bit
    jne food_error_24_bit_RGB ; check for if 24 bit RGB
    mov eax,[esi+30] ; obtain compression type 
    cmp eax,0 ; is the image compressed? 0 = not compressed
    jne food_error_commression ; check if no commression

    ; calculate histogram of image. 30 - 44 initialize value that we need for filling histogram loop 
    ; 30-37 calculate number of pixels
    mov ecx,[esi+34] ; obtain image size
    mov eax,0xffff; emptying the left half of ECX
    and eax,ecx ; obtain 1st 2 bytes only of image size coz, 200x200=40000 occupies only 2 bytes 
    mov edx,0xffff0000
    and edx,ecx ;zeroing right half
    shr edx,16 ; shifting left half to right.
    mov ecx,3  ;ax = (size / 3) = number of pixel
    div ecx ; EAX is divided by ECX. EDX stores the remainder and EAX stores the quotient.

    ; 39-43 for get address of first green component
    mov cx,ax ; we use ecx as counter by initializing # of pixels
    mov eax,[esi+10] ; obtain offset of the first pixel.
    inc eax ; go to green component of the 1st pixel
    add esi,eax  ; obtain address of first green component pixel
    mov edi,histogram_buffer ; obtain address of histogram buffer

food_histogram_loop:
    mov al,[esi] ; <<---------------------------------------------
    movzx eax,al ; <<---------------------------------------------
    shl eax,2 ; <<---------------------------------------------
    add eax,edi ; obtain address of element histogram[i]
    mov ebx,[eax] ; obtain value of element histogram[i]
    inc ebx ; ebx = ebx + 1 ; increment histogram element histogram[i]
    mov [eax],ebx ; save histogram[i] to memory
    add esi,3 ; update esi to go to next pixel
    dec ecx ; derement ecx to go to previous index of histogram
    cmp ecx,0 ; test if the loop ended
    jne food_histogram_loop

    ; calculate mode
    mov eax,255
    shl eax,2 ; eax = eax * 4
    mov esi,eax
    add esi,edi ; obtain address of element histogram[i]
    mov edx,[esi] ; obtain value of element histogram[i]
    mov ecx,255 ; initialze ecx we use it as counter
    mov ebx,255 ; initialze ebx
    jmp food_mode_loop_check

food_mode_loop:
    add esi,-4
    mov eax,[esi]
    cmp eax,edx
    jle food_mode_loop_check  ; jmup if eax <= max
    ; if eax > max  max = eax ; ebx = i
    mov edx,eax
    mov ebx,ecx
food_mode_loop_check:; test end of loop
    dec ecx ; decrement the index of histogram[i]
    cmp ecx,0 ; compare ecx with zero and set the flag so that JGE can use it
    jge food_mode_loop ; jump if greater or equal to zero

    ; ebx = mode
    cmp ebx,0x20
    jle food_cur
    cmp ebx,0x39
    jle food_acb
    mov eax,3 ; adz
    jmp food_done

food_cur:
    mov eax,1 ; cur
    jmp food_done

food_acb:
    mov eax,2 ; acb
    jmp food_done

food_error_width:
    mov eax,-1
    jmp food_done

food_error_height:
    mov eax,-2
    jmp food_done

food_error_24_bit_RGB:
    mov eax,-3
    jmp food_done

food_error_commression:
    mov eax,-4

food_done:
    pop edi
    pop ebx
    pop edx
    pop ecx
    pop esi

    leave
    ret

What are the arrow pointed lines doing here?

Are they redundant?

assembly
bitmap
x86
asked on Stack Overflow Jun 11, 2019 by user366312

1 Answer

2

The three instructions, when taken together, have the effect of storing four times the byte value pointed to by esi into eax.

mov al,[esi] loads the byte into al.
movzx eax,al will zero extend this byte to the full eax register.
shl eax,2 will shift this 32 bit value left two bits, essentially multiplying the value by 4.

This could be combined with the next line and condensed to two instructions:

movzx eax,byte ptr [esi]
lea eax,[edi+4*eax]
answered on Stack Overflow Jun 11, 2019 by 1201ProgramAlarm • edited Jun 11, 2019 by 1201ProgramAlarm

User contributions licensed under CC BY-SA 3.0