简体   繁体   English

如何在汇编语言(x86)上比较2个数组?

[英]How to compare 2 arrays on assembly language (x86)?

    .MODEL  SMALL
    .STACK  64
    .DATA

    LIST1 DB 1H,0ABH,2H,3AH,12H,0DAH
    LIST2 DB 3H,7H,0BCH,0A8H,0C2H,0DAH
    LIST3 DB 6 DUP (?)

    .CODE


MAIN    PROC    FAR
    MOV     AX, @data
    MOV DS, AX

    MOV CX,6H
    LEA SI,LIST1
    LEA BX,LIST2
    LEA DI,LIST3

A1: MOV AL,[SI]
    ADD AL,BX
    MOV [DI],AL
    INC SI
    INC BX
    INC DI
    LOOP    A1

I want to compare list1 & list2 and put the greater number in list3. 我想比较list1和list2并将更大的数字放在list3中。 How to do that? 怎么做?

Here's an alternative A1 loop. 这是另一个A1循环。 I think your setup instructions are OK. 我认为您的设置说明还可以。 I'm assuming Intel syntax on operand ordering for instructions. 我假设英特尔对操作数排序的语法说明。

A1:
    MOV   AL,[SI]     ; get the next byte from LIST1
    ADD   AH,[BX]     ; get the next byte from LIST2

    CMP   AL,AH       ; compare bytes from 1 & 2
    JGT   BIGGER2     ; jump if LIST1 byte > LIST2 byte

    MOV   [DI],AL     ; move LIST1 byte to LIST2
    JMP   NEXT

BIGGER2:
    MOV   [DI],AH     ; move LIST2 byte to LIST3

NEXT:
    INC   SI          ; point to next LIST1 byte
    INC   BX          ; point to next LIST2 byte
    INC   DI          ; point to next LIST3 byte
    LOOP  A1          ; go to the top for the next byte

In solving a problem like this, you can actually start by writing out the comments. 解决此类问题时,实际上可以先写出注释。 If you were to take the comments above by themselves, they form the low level steps in English of what you want to do. 如果您要自己接受上面的评论,则它们会构成您想要做的英语的低级步骤。 Then you can translate those steps into the needed assembly language. 然后,您可以将这些步骤转换为所需的汇编语言。 You can then also optimize if needed. 然后,您还可以根据需要进行优化。

[EDIT] [编辑]

Note also that, as @Powerslave showed in his answer, you can shorten this a bit using the built-in x86 "string" instruction, cmpsb . 还要注意,正如@Powerslave在他的回答中显示的那样,您可以使用内置的x86“ string”指令cmpsb缩短一点。 That assumes source and destination lists are pointed to by si and di . 假定源列表和目标列表由sidi指向。

For addition, the following puts the SUM of LIST1 and LIST2 into LIST3 . 另外,以下将LIST1LIST2放入LIST3 Note that you allocated bytes for LIST3 but when you sum LIST1 and LIST2 elements, you'll get an overflow if you keep them as bytes. 请注意,您为LIST3分配了字节,但是当对LIST1LIST2元素求和时,如果将它们保留为字节,则会溢出。 So I will use words for the sum: 因此,我将用单词来表示总和:

LIST3 DW 6 DUP (?)

...

    CLR   AH
A1:
    MOV   AL,[SI]     ; get the next byte from LIST1
    MOV   [DI],AX     ; move the value (byte) to LIST3
    MOV   AL,[BX]     ; get the value (byte) from LIST2
    ADD   [DI],AX     ; add the LIST2 value to LIST3 (word)
    INC   SI          ; point to next LIST1 byte
    INC   BX          ; point to next LIST2 byte
    ADD   DI,2        ; point to next LIST3 word
    LOOP  A1          ; go to the top for the next byte

A solution would be 一个解决方案是

; ES == DS

lea si,[LIST1]
lea di,[LIST2]
lea bx,[LIST3]
mov cx,LENGTH_OF_LISTS

inspect_lists:
    cmpsb
    jg first_is_greater            ; Use JA instead for unsigned integers
    mov al,[byte ptr es:di + 0]
    jmp store_result

    first_is_greater:
    mov al,[byte ptr ds:si + 0]

    store_result:
    mov [byte ptr ds:bx + 0],al
    inc bx
loop inspect_lists

inspect_lists supposed to be your A1 loop. inspect_lists应该是您的A1循环。

cmpsb , in one step, does compare [DS:SI] with [ES:DI] cmpsb一步将[DS:SI][ES:DI]
(essentially a virtual cmp [byte ptr ds:si],[byte ptr es:di] ) and increments (or decrements if DF is 1) the SI and DI pointers so that you don't have to worry about them yourself. (实际上是虚拟cmp [byte ptr ds:si],[byte ptr es:di] )并递增(如果DF为1,则递减) SIDI指针,因此您不必自己担心它们。

You still need to adjust BX in order to iterate through LIST3 . 您仍然需要调整BX以便遍历LIST3

The only thing to do besides that is to decide which value to store at [DS:BX] ... 唯一要做的就是确定要在[DS:BX]存储哪个值...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM