以下程序根据直方图和模式计算来检测图像。
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
这里的箭头线是做什么的?
它们多余吗?
答案 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]