Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 使用偏移量计算程序集从迷宫中获取字节_Assembly_Masm_8086 - Fatal编程技术网

Assembly 使用偏移量计算程序集从迷宫中获取字节

Assembly 使用偏移量计算程序集从迷宫中获取字节,assembly,masm,8086,Assembly,Masm,8086,对于这个项目,我得到了一个迷宫,表示为一个字节数组,包含20h(可以移动到的空白空间)或任何其他内容(不能移动到的完整空间) 从驱动程序中,我得到了 x pointer si y pointer di dir pointer bx E=1 S=2 W=3 N=4 maze pointer bp 一旦我确定一个空间是否为空,并且计算了我正在测试的字节所在的迷宫中的偏移量,我就知道了如何修改寄存器 公式:(Y-1)*30+(X-1)计算我要测试到数组中的字节的偏移量

对于这个项目,我得到了一个迷宫,表示为一个字节数组,包含20h(可以移动到的空白空间)或任何其他内容(不能移动到的完整空间)

从驱动程序中,我得到了

x    pointer   si
y    pointer   di
dir  pointer   bx  E=1 S=2 W=3 N=4
maze pointer   bp
一旦我确定一个空间是否为空,并且计算了我正在测试的字节所在的迷宫中的偏移量,我就知道了如何修改寄存器

公式:(Y-1)*30+(X-1)计算我要测试到数组中的字节的偏移量。30是迷宫的宽度

所以本质上我需要做一些事情

mov al,ds:[bp+((Y-1)*30+(X-1))]

然后将迷宫中存储在al中的字节与20h进行比较,看我是否可以移动到那个位置

我目前的代码是:哪个工作正常

    mov    al, dl               ; move the y position being tested into the AL register
    dec    al                   ; decrement the AL register for the offset calculation
    mul    [value]              ; multiply the al register by 30 and store the product in ax
    add    al, dh               ; add the x position to the ax
    adc    ah, 0
    dec    ax                   ; decrement the ax register for the offset calculation
    push   si                   ; Preserve SI
    mov    si, ax               ; move the offset calculated inside of ax into si
    mov    al, ds:[bp + si]     ; access the maze using data segment override with offset si
    pop    si                   ; Restore SI
    cmp    al, 20h              ; position in the maze at the offset empty
    jne    testnext             ; yes jump to the exit function              
我们根据效率进行评分,并指出我们可以使用“高级间接寻址”来避免在ax中进行所有这些偏移量计算,因此如果您知道如何进行,我将不胜感激

以下是完整的代码:

;---------------------------------------------------------------------
; Program:   nextval subroutine
;
; Function:  Find next mouse move in an array 15 by 30.
;            We can move into a position if its contents is blank ( 20h ).
;
; Input:     Calling sequence is:
;            x    pointer   si
;            y    pointer   di
;            dir  pointer   bx  E=1 S=2 W=3 N=4
;            maze pointer   bp
;
; Output:    x,y,dir modified in caller's data segment
;
; Owner:     Dana A. Lasher
;
; Date:      Update Reason
; --------------------------
; 11/06/2016 Original version
;
;
;---------------------------------------
         .model    small               ;64k code and 64k data
         .8086                         ;only allow 8086 instructions
         public    nextval             ;allow extrnal programs to call
;---------------------------------------


;---------------------------------------
         .data                         ;start the data segment
;---------------------------------------
value db 30
;---------------------------------------
         .code                         ;start the code segment
;---------------------------------------
; Save any modified registers
;---------------------------------------
nextval:
    push   cx                          ; save cx register
    push   ax                          ; save ax register
    push   dx                          ; save dx register
    mov    cl, 0                       ; set testing phase to 0 stored in ch
;---------------------------------------
; Code to make 1 move in the maze
;---------------------------------------

testnext:
    mov    ax, 0
    mov    dx, 0
    mov    dh, [si]
    mov    dl, [di]
    inc    cl                          ; increment the testing phase

direction:
    cmp    byte ptr [bx], 1            ; is the moving direction East
    je     goingeast                   ; yes, jump to the going east function
    cmp    byte ptr [bx], 2            ; is the moving direction south
    je     goingsouth                  ; yes, jump to the going south function
    cmp    byte ptr [bx], 3            ; is the moving direction west
    je     goingwest                   ; yes, jump to the going west function
    cmp    byte ptr [bx], 4            ; is the moving direction north
    je     goingnorth                  ; yes, jump to the going north function
    jmp    exit
;---------------------------------------
; Going East        Check order: N-E-S-W
;---------------------------------------
goingeast: 
    cmp    cl, 1                       ; is the testing phase phase 1
    je     checknorth                  ; yes, check to see if a move north is valid
    cmp    cl, 2                       ; is the testing phase phase 2
    je     checkeast                   ; yes, check to see if a move east is valid
    cmp    cl, 3                       ; is the testing phase phase 3
    je     checksouth                  ; yes, check to see if a move south is valid 
    cmp    cl, 4                       ; is the testing phase phase 4
    je     checkwest                   ; yes, check to see if a move west is valid 
    jmp    exit 
;---------------------------------------
; Going South       Check order: E-S-W-N
;---------------------------------------
goingsouth:
    cmp    cl, 1                       ; is the testing phase phase 1
    je     checkeast                   ; yes, check to see if a move east is valid
    cmp    cl, 2                       ; is the testing phase phase 2
    je     checksouth                  ; yes, check to see if a move south is valid 
    cmp    cl, 3                       ; is the testing phase phase 3
    je     checkwest                   ; yes, check to see if a move west is valid 
    cmp    cl, 4                       ; is the testing phase phase 4
    je     checknorth                  ; yes, check to see if a move north is valid
    jmp    exit 
;---------------------------------------
; Going West        Check order: S-W-N-E
;---------------------------------------
goingwest: 
    cmp    cl, 1                       ; is the testing phase phase 1
    je     checksouth                  ; yes, check to see if a move south is valid 
    cmp    cl, 2                       ; is the testing phase phase 2
    je     checkwest                   ; yes, check to see if a move west is valid 
    cmp    cl, 3                       ; is the testing phase phase 3
    je     checknorth                  ; yes, check to see if a move north is valid
    cmp    cl, 4                       ; is the testing phase phase 4
    je     checkeast                   ; yes, check to see if a move east is valid
    jmp    exit 
;---------------------------------------
; Going North       Check order: W-N-E-S
;---------------------------------------
goingnorth:
    cmp    cl, 1                       ; is the testing phase phase 1
    je     checkwest                   ; yes, check to see if a move west is valid 
    cmp    cl, 2                       ; is the testing phase phase 2
    je     checknorth                  ; yes, check to see if a move north is valid
    cmp    cl, 3                       ; is the testing phase phase 3
    je     checkeast                   ; yes, check to see if a move east is valid
    cmp    cl, 4                       ; is the testing phase phase 4
    je     checksouth                  ; yes, check to see if a move south is valid 
    jmp    exit 
;---------------------------------------
; Check East                X + 1 Y same
;---------------------------------------
checkeast:
    inc    dh                          ; incremement dh to the x position being tested
    mov    ch, 1                       ; update the testing direction ch to 1
 
    mov    al, dl               ; move the y position being tested into the AL register
    dec    al                   ; decrement the AL register for the offset calculation
    mul    [value]              ; multiply the al register by 30 and store the product in ax
    add    al, dh               ; add the x position to the ax
    adc    ah, 0
    dec    ax                   ; decrement the ax register for the offset calculation
    push   si                   ; Preserve SI
    mov    si, ax               ; move the offset calculated inside of ax into si
    mov    al, ds:[bp + si]     ; access the maze using data segment override with offset si
    pop    si                   ; Restore SI
    cmp    al, 20h              ; position in the maze at the offset empty
    jne    testnext             ; yes jump to the exit function
 
    inc    byte ptr [si]          ; update x position
    mov    byte ptr [bx], 1           ; update moving direction
    jmp    exit
;---------------------------------------
; Check South               X same Y + 1
;---------------------------------------
checksouth:
    inc    dl                          ; increment dl to the y position being tested
    mov    ch, 2                       ; update the testing direction ch to 2

    mov    al, dl           ; move the y position being tested into the AL register
    dec    al               ; decrement the AL register for the offset calculation
    mul    [value]          ; multiply the al register by 30 and store the product in ax
    add    al, DH           ; add the x position to the ax
    adc    ah, 0
    dec    ax               ; decrement the ax register for the offset calculation
    push   si               ; Preserve SI
    mov    si, ax           ; move the offset calculated inside of ax into si
    mov    al, ds:[bp + si] ; access the maze using data segment override with offset si
    pop    si               ; Restore SI
    cmp    al, 20h          ; position in the maze at the offset empty
    jne    testnext             ; yes jump to the exit function
 
    inc    byte ptr [di]          ; update x position
    mov    byte ptr [bx], 2           ; update moving direction
    jmp    exit
;---------------------------------------
; Check West                X - 1 Y same
;---------------------------------------
checkwest:
    dec    dh                          ; update dh to the x position being tested
    mov    ch, 3                       ; update the testing direction ch to 3

    mov    al, dl           ; move the y position being tested into the AL register
    dec    al               ; decrement the AL register for the offset calculation
    mul    [value]          ; multiply the al register by 30 and store the product in ax
    add    al, dh           ; add the x position to the ax
    adc    ah, 0
    dec    ax               ; decrement the ax register for the offset calculation
    push   si               ; Preserve SI
    mov    si, ax           ; move the offset calculated inside of ax into si
    mov    al, ds:[bp + si] ; access the maze using data segment override with offset si
    pop    si               ; Restore SI
    cmp    al, 20h          ; position in the maze at the offset empty
    jne    testnext             ; yes jump to the exit function

    dec    byte ptr [si]          ; update x position
    mov    byte ptr [bx], 3           ; update moving direction
    jmp    exit
;---------------------------------------
; Check North               X same Y - 1
;---------------------------------------
checknorth:
    dec    dl                          ; update dl to the y position being tested
    mov    ch, 4                       ; update the testing direction ch to 4

    mov    al, dl           ; move the y position being tested into the AL register
    dec    al               ; decrement the AL register for the offset calculation
    mul    [value]          ; multiply the al register by 30 and store the product in ax
    add    al, dh           ; add the x position to the ax
    adc    ah, 0
    dec    ax               ; decrement the ax register for the offset calculation
    push   si               ; Preserve SI
    mov    si, ax           ; move the offset calculated inside of ax into si
    mov    al, ds:[bp + si] ; access the maze using data segment override with offset si
    pop    si               ; Restore SI
    cmp    al, 20h          ; position in the maze at the offset empty
    jne    testnext             ; yes jump to the exit function
 
    dec    byte ptr [di]           ; update x position
    mov    byte ptr [bx], 4           ; update moving direction
    jmp    exit
;---------------------------------------
; Restore registers and return
;----------------d-----------------------
exit:

    ; here the dx and cx registers should still have the needed information
    pop    dx                          ; restore the dx register
    pop    ax                          ; restore the ax register
    pop    cx                          ; restore the cx register
    ret                                ; return
;---------------------------------------
    end    nextval

下一个代码片段删去了一些指令

  • 知道迷宫的宽度是30,我们就可以不用从内存中检索该值
  • 我们可以在
    CMP
    指令的位移字段中隐藏从1基到0基的转换
  • 我们可以避免
    push
    pop
    ,并且仍然保留
    SI
    寄存器

下一个代码片段删去了一些指令

  • 知道迷宫的宽度是30,我们就可以不用从内存中检索该值
  • 我们可以在
    CMP
    指令的位移字段中隐藏从1基到0基的转换
  • 我们可以避免
    push
    pop
    ,并且仍然保留
    SI
    寄存器

表查找的替代方法:30是
32-2
。8086位移位不大(每个计数IIRC 1个周期),但
(表查找的替代方法:30是
32-2
。8086位移位不大(每个计数IIRC 1个周期),但
(x
    mov    al, 30
    mul    dl            <<< AX is too high by 30
    add    al, dh
    adc    ah, 0         <<< AX is too high by 30 + 1
    xchg   si, ax        ; Preserve SI and load index   
    cmp    byte ptr ds:[bp + si - 31], 20h
    mov    si, ax        ; Restore SI
    jne    testnext
list  dw  0, 30, 60, 90, 120, ...
          ^  ^
          |  | if Y=2
          | if Y==1