汇编输入的最大值

时间:2017-10-18 06:09:08

标签: assembly x86

简单的汇编程序,用于吐出两个用户输入数字中较大的一个。我无法正确输出输出。例如,如果我输入45和55,最大值将是55,但是当我尝试反向55和45(答案应该仍然是55)时,我得到45.看来这个程序只输出输入的第二个值,存储在EAX中。非常感谢任何帮助。

.586
.MODEL FLAT

INCLUDE io.h

.STACK 4096

.DATA
value1 DWORD ?
value2 DWORD ?

prompt1 BYTE "Enter the first number", 0
prompt2 BYTE "Enter the second number", 0
string BYTE 40 DUP (?)

resultLbl BYTE  "The maximum value you entered was:", 0

.CODE

_MainProc PROC      
input prompt1, string, 40       ;get user input value1
atod string                     ;convert input (ASCII) to integer
mov ebx, eax

input prompt2, string, 40   ; repeat for value2
atod string
mov value2, eax

cmp eax, ebx                ;compare user inputs

jg greater_than     ;jump conditional if value 1 is greater then value 2

    greater_than:   ;condition if greater than ouput
        dtoa value1, eax                    ;decimal to ASC for output of 
integer value stored at ebx
        output  resultLbl, value1           ;output value 1
            jmp exit                    

    less_than:  ;condition if less than ouput
        dtoa value1, eax
        output  resultLbl, value2           ;else output value 2    
            jmp exit

    exit:   ;quit jump              ;end if/else conditional

    mov eax, 0          ;clear memory
    mov ebx, 0
    ret
_MainProc ENDP
END

3 个答案:

答案 0 :(得分:1)

问题在于指令的顺序。即使操作数1小于操作数2,它唯一的区别是jg greater_than不会导致显式跳转到greater_than标签。但是,下一组指令是打印操作数1,即执行控制将变为“内部”greater_than标签。为什么?那是因为下一条指令dtoa value1, eax正好在jg greater_than之后。所以,你现在看到了问题吗?如果操作数1小于操作数2,则不会阻止操作数1的打印。您的所有代码都是为了确保程序打印value1以确保操作数1和操作数是否为1。操作数2.

您的代码等同于以下C代码:

if (op1>op2)goto gt;
gt: 
printf("%d",op1);
exit(0);

lt:
printf("%d",op2);
exit(0);

虽然您打算执行以下操作:

if(op1>op2){
 printf("%d",op1);
 exit(0);
}

printf("%d",op2);
exit(0);

要解决此问题,您必须更改指令的顺序,如下所示:

jg greater_than     ;jump conditional if value 1 is greater then value 2

    less_than:  ;condition if less than ouput
        dtoa value1, ebx
        output  resultLbl, value1           ;else output value 2    
            jmp exit

    greater_than:   ;condition if greater than ouput
        dtoa value1, eax                    ;decimal to ASC for output of integer value stored at eax
        output  resultLbl, value1           ;output value 1
            jmp exit

上述代码确保在操作数1>时阻止执行less_than标签内的代码。操作数2,通过明确跳转到greater_than标签。当操作数1< =操作数2时,不进行显式跳转,并执行序列中的下一条指令。在这种情况下,当操作数1< =操作数2时执行less_than内的内容。

简而言之,条件跳转仅在条件满足时才会导致跳转,否则执行序列中的下一条指令。您有责任按照正确的顺序执行说明。它们不像高级条件结构,如if ...... else。

更新:请注意,我的整个解决方案仅使用value1

答案 1 :(得分:1)

正如Mayank Verma所说,如果你在这条指令之后立即跳过“jg greater_than”,即使EAX< = EBX你执行了应该为EAX> EBX条件执行的相同指令,你也绝不会执行跳转到less_than。标签“less_than”可以删除。你应该写:

    CMP EAX,EBX
     JG greater_than

;less_than
   dtoa value1, eax
 output resultLbl, value2
    jmp exit

greater_than:
integer value stored at ebx
 output resultLbl, value1

exit:

但我有一个新的解决方案。这是一个优化的MAX(A,B)函数:

;  INPUT: EAX, EBX
; OUTPUT: EAX <- The maximum value between EAX, EBX

   CMP EAX,EBX
 CMOVL EAX,EBX

答案 2 :(得分:0)

输入了3个值。这看起来有用吗?

.586
.MODEL FLAT

INCLUDE io.h

.STACK 4096

.DATA
value1 DWORD ?
value2 DWORD ?
value3 DWORD ?

titleLbl BYTE   "MAXIMUM NUMBERS",0
formula BYTE "Taking any THREE random user input numbers, this program can 
determine which of those numbers is greater.",0

prompt1 BYTE "Enter the first number",0
prompt2 BYTE "Enter the second number",0
prompt3 BYTE "Enter the third number",0
string BYTE 40 DUP (?)

resultLbl BYTE  "The maximum value you entered was:", 0
max_value BYTE 11 DUP (?), 0

.CODE

_MainProc PROC  
output titleLbl, formula

input prompt1, string, 40       ;get user input value1
atod string                     ;convert input (ASCII) to integer
mov ebx, eax

input prompt2, string, 40   ; repeat for value2
atod string
mov ecx, eax

input prompt3, string, 40   ; repeat for value2
atod string
mov value3, eax

cmp ebx, ecx                ;compare user inputs

jg greater_than     ;jump conditional if value 2 is greater then value 3

less_than:  ;condition if less than ouput
    cmp eax, ecx

    jg greater_than_again   ;jump conditional if 2 is greater than 1

    less_than_again: 
        dtoa max_value, ecx
        output  resultLbl, max_value          ;else output value 2    
        jmp exit

    greater_than_again:
    dtoa max_value, eax                    ;decimal to ASC for output of 
 integer value stored at eax
    output  resultLbl, max_value           ;output value 1
        jmp exit

greater_than:   ;condition if greater than ouput
    cmp eax, ebx

    jg greater_than_again   ;jump conditional if 2 is greater than 1

    less_than_again2: 
        dtoa max_value, ebx
        output  resultLbl, max_value          ;else output value 2    
        jmp exit

    greater_than_again2:
    dtoa max_value, eax                    ;decimal to ASC for output of 
 integer value stored at eax
    output  resultLbl, max_value           ;output value 1
        jmp exit

    exit:   ;quit jump              ;end if/else conditional

    mov eax, 0          ;clear memory
    mov ebx, 0
    mov ecx, 0
    ret
 _MainProc ENDP
 END