INT_MAX equ 7FFF_FFFFh SECTION .text global find_smallest_int find_smallest_int: ; If the array is empty (size = 0) then we want to return ; without reading from the array at all. The value to return ; then logically should be the highest possible number for a ; 32-bit signed integer. This is called INT_MAX in the C ; header limits.h and for 32-bit int is equal to 7FFF_FFFFh. ; ; If the array is not empty, the first iteration will then ; always leave our result register equal to the value in ; the first array entry. This is either equal to INT_MAX ; again, or less than that. mov eax, INT_MAX ; esi is the second argument to our function, which is ; declared as int find_smallest_int(int *, unsigned int). ; It represents the length of the array. We use this ; as a counter. rsi (and its part esi) need not be preserved ; across function calls for the AMD64 psABI that is used by ; Linux, see https://stackoverflow.com/a/40348010/738287 ; Check for an initial zero value in esi. If this is found, ; skip the loop without any iteration (while x do y) and ; return eax as initialised to INT_MAX at the start. test esi, esi jz .end .loop: ; If eax is greater than or equal to dword [rdi], we'll ; reassign eax to that dword, the new smallest-yet value. cmp eax, dword [rdi] cmovge eax, dword [rdi] ; Set rdi to point to the next value in the array. add rdi, 4 ; Subtract one from our counter. This started as ; the number of elements in the array - when it ; gets to 0, we'll have looped through the entire thing. dec esi ; Check to see if we've reached the end of the array. ; To do this, we use the Zero Flag as set by the prior ; dec instruction. If esi has reached zero yet (ZR) then ; we do not continue looping. In that case, we return the ; smallest value found yet (which is in eax at the moment). ; ; Else, we jump to the start of the loop to begin the next ; iteration. jnz .loop .end: retn