比较8086汇编语言中的十六进制整数不起作用

时间:2015-04-13 09:47:20

标签: assembly x86-16

我正在尝试编写一个8086程序,用于比较以十六进制编写的整数数组。我知道最高的数字是0xFF,但它不会导致最大值。 (我也不确定我是否正确地结束了这个程序。这是我的代码:

DATA SEGMENT    ;declares the data segment  

SIZEA   DW 10  
MAXV    DW 0  
INTARR  DW 0x1,0x2,0x4,0xFF,0xFE,0xFA,0x7,0x9,0x8,0xFD  

DATA ENDS       ;ends the data segment

CODE SEGMENT    ;declares the code segment
START:          ;declares start label

        MOV AX,DATA         ;moves the data to the AX register
        MOV DS,AX           ;moves the date from the AX reg to DS

        LEA SI,INTARR       ;loads the address of INTARR to SI

        MOV BX,INTARR[SI]   ;loads the first array item into BX
        MOV CX, SIZEA       ;loads the size of the array to CX
        MOV DX, MAXV        ;loads the maxv variable to DX

THELOOP:        ;This is where the loop starts
        MOV BX,INTARR[SI]   ;loads the array item at index SI
        CMP MAXV,BX         ;compares BX to the value of MAXV                                          
        JGE SKIP            ;goes to SKIP if MAXV is greater
        MOV MAXV,BX         ;if BX is greater BX moves to DX

SKIP:           ;this is the skip label
        INC SI              ;increments SI for the next loop
        LOOP THELOOP        ;loops

CODE ENDS       ;ends the segment
END START       ;ends start label

 ret

我正在使用emu8086。当我模拟它并观察变量时,它表明MAXV是0900h。它运行大约20个NOP命令。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:2)

好的,这是我在您的代码中看到的所有问题:

  1. SIZEA和MAXV是地址。因此,当您编写MOV CX,SIZEA时,您不会加载SIZEA的内容,而是加载其地址。这不是你想要的。你想写MOV CX,[SIZEA]
  2. 我不确定emu8086是如何工作的,因为我从未使用它。但是,您设置数据段的方式看起来很可疑。您是否已将偏移地址加载到段寄存器中?
  3. ret是您的功能的一部分,应该在您的代码段中。但是我不知道是否有任何有效的代码可以返回。
  4. 第一个lea指令没有做你想做的事情,只需删除它
  5. 第一个MOV BX,INTARR[SI]是多余的,可以删除。
  6. 您只将SI增加一个字节,但数组条目的长度是一个字(2字节)
  7. 以下是我更改以使代码正常工作的内容。请注意,这不适用于emu8086,但适用于标准NASM:

    START:  XOR AX,AX       ; Clear data segment, may not be how you do it on emu8086
            MOV DS,AX       
            MOV SI,AX       ; Clear the Source index        
            MOV CX,[SIZEA]
            XOR DX,DX       ; Note how I just clear DX, no need to load 0 from memory
                            ; DX will then contain highest value    
    THELOOP:MOV BX,[INTARR+SI] ; I am just using this syntax because it is the standard for NASM
            CMP DX,BX       ; Compare max value with current value
            JGE SKIP
            MOV DX,BX       ; Now just move the max value to the register
    SKIP:   ADD SI,2        ; Move by 2 bytes since it is a word array
            LOOP THELOOP    ;
            MOV [MAXV],DX   ; Now you can save the highest value to memory
                            ; less memory access so faster execution
            RET
    
    ; DATA
    SIZEA   DW      10
    MAXV    DW      0
    INTARR  DW      0x1,0x2,0x4,0xFF,0xFE,0xFA,0x7,0x9,0x8,0xFD