Assembly 程序集查找两个值的最大值

Assembly 程序集查找两个值的最大值,assembly,fasm,Assembly,Fasm,我试图找到两个值之间的最大值 _FindMax: push ebp mov ebp, esp mov eax, dword [ebp+12] ; get fist argument mov ebx, dword [ebp+8] ; get second argument cmp eax, ebx jl LESS ; if eax less to LESS LESS: mov eax, ebx ; ebx i

我试图找到两个值之间的最大值

_FindMax:
    push ebp
    mov ebp, esp

    mov eax, dword [ebp+12]  ; get fist argument
    mov ebx, dword [ebp+8]   ; get second argument


    cmp eax, ebx
    jl LESS       ; if eax less to LESS

    LESS:
    mov eax, ebx ; ebx is greate and return it

    mov esp, ebp
    pop ebp

    ret

但问题是:标签总是在执行。例如,如果参数相等,则执行LESS:label。为什么???

无论是否执行分支,LESS中的代码始终被执行。您需要跳过不想执行的代码:

_FindMax:
    push ebp
    mov ebp, esp

    mov eax, dword [ebp+12]  ; get fist argument
    mov ebx, dword [ebp+8]   ; get second argument


    ; invert the condition, and jump over the code to skip
    cmp eax, ebx
    jge SKIP       ; jmp and return, if aex is the larger one

    mov eax, ebx   ; ax is NOT larger, so return ebx

    SKIP:
    mov esp, ebp
    pop ebp

    ret

始终执行LESS中的代码,无论是否执行分支。您需要跳过不想执行的代码:

_FindMax:
    push ebp
    mov ebp, esp

    mov eax, dword [ebp+12]  ; get fist argument
    mov ebx, dword [ebp+8]   ; get second argument


    ; invert the condition, and jump over the code to skip
    cmp eax, ebx
    jge SKIP       ; jmp and return, if aex is the larger one

    mov eax, ebx   ; ax is NOT larger, so return ebx

    SKIP:
    mov esp, ebp
    pop ebp

    ret

实现这一点的真正有效方法是(假设您至少有一个P6系列处理器):


此代码省略堆栈帧(EBP),并使用内联
MOV
操作进行比较。尽管如此,返回值仍然在EAX中(假设您至少有一个P6系列处理器),实现这一点的真正有效方法是:


此代码省略堆栈帧(EBP),并使用内联
MOV
操作进行比较。尽管如此,返回值仍在
EAX

中。如果不执行分支,代码将自动运行到更少的位置。您必须跳过要跳过的代码当“不少于”为真时(我的意思是当
jl
未跳过时),您希望它执行什么?顺便说一句,您也可以使用有条件的
cmovCC
,在这种情况下
cmovl eax,ebx
将在不进行分支的情况下解决它。谢谢大家。问题已解决。如果不执行分支,代码将自动运行到更少的内存中。您必须跳过要跳过的代码当“不少于”为真时(我的意思是当
jl
未跳过时),您希望它执行什么?顺便说一句,您也可以使用有条件的
cmovCC
,在这种情况下
cmovl eax,ebx
将在不进行分支的情况下解决它。谢谢大家。问题解决了。你能评论一下为什么这是有效的吗?是因为它避免了跳转吗?因为它有(接近)最少的指令,避免堆栈帧,并且没有跳转。一条指令更少的版本是可能的:
mov-eax,dword[esp+8]--cmp-eax,dword[esp+4]--cmovl-eax,dword[esp+4]--ret
。但是它可能不会比上面的更快-但是,它节省了一个寄存器。你能评论一下为什么这是有效的吗?是因为它避免了跳转吗?因为它有(接近)最少的指令,避免堆栈帧,并且没有跳转。一条指令更少的版本是可能的:
mov-eax,dword[esp+8]--cmp-eax,dword[esp+4]--cmovl-eax,dword[esp+4]--ret
。但是它可能并不比上面的一个快,但是,它保存了一个寄存器。