首页 > 解决方案 > 源代码中的 3 条尖线是多余的吗?

问题描述

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

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

箭头指向的线在这里做什么?

它们是多余的吗?

标签: assemblybitmapx86

解决方案


esi这三个指令放在一起时,具有存储into指向的字节值的四倍的效果eax

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

这可以与下一行结合起来并浓缩为两条指令:

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

推荐阅读