源代码中的3条尖线是否多余?

时间:2019-06-11 03:26:32

标签: assembly bitmap x86

以下程序根据直方图和模式计算来检测图像。

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

这里的箭头线是做什么的?

它们多余吗?

1 个答案:

答案 0 :(得分:2)

这三个指令一起使用,具有将esi指向的字节值的四倍存储到eax中的作用。

mov al,[esi]将字节加载到al中。
movzx eax,al将将该字节零扩展到完整的eax寄存器。
shl eax,2会将这个32位值左移两位,实际上是将该值乘以4。

这可以与下一行结合使用,并精简为两条说明:

movzx eax,byte ptr [esi]
lea eax,[edi+4*eax]