汇编器使用段寄存器

Tri*_*iak 2 x86 assembly masm

最近,我正在编写程序集,并且我编写的程序在DOSBox下运行没有任何问题。现在,我需要使用DOS将同一程序移植到实际计算机中,但是会出现一些问题。

首先,在DOSBox下,我正在使用ML进行编译,但是在真正的PC上,一旦输入ML,它就会说:

该程序不能在DOS模式下运行。

因此,我一直在寻找一种解决方案,并发现MASM可以毫无问题地编译asm程序。不幸的是,我需要移植的程序在编译时报告严重错误(仅1种类型)。

错误A2061:段寄存器使用不当

出现这些问题的路线如下

...
CARLOC EQU $-2
...
MOV [WORD PTR DS:CARLOC],DX
...
Run Code Online (Sandbox Code Playgroud)

以下代码也会出现相同的问题

...
MOV ES,CX
MOV AL, [BYTE PTR ES:0017H]
...
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经尝试将BYTE PTR [ES:0017H] 产生相同错误的BYTE PTR更改为

BYTE PTR ES:0017H 成功地在 其中编译了代码,该程序运行了但无法正常运行

注意:我不知道当前在哪种架构下工作。可能无法物理访问该计算机,但是如果我可以键入一些代码来查看屏幕上的信息,我将很高兴这样做。

代码在这里,如果我需要在这里粘贴它就太长了,然后确定,但是直到那时https://pastecode.xyz/view/5f332efc

PC说它运行MSDOS 6

Pet*_*des 5

(更新:Michael Petch说一些与 MASM或MASM兼容的汇编器允许在括号使用大小和段覆盖。但是update2:并非全部,因此这实际上可能是问题所在。至少是标准样式,因此我建议始终这样做)


使用所需的常规MASM语法MOV [CARLOC], DX 根据您声明的方式carloc,您可能仍然需要mov word ptr [CARLOC], dx,但是DS:已经是默认段。

如果您想对此进行明确说明,MOV word ptr ds:[CARLOC], dx但我建议在asm源代码中省略冗余DS前缀,因为某些汇编程序的机器代码中包括冗余DS前缀!DS:唯一不是唯一的时间是当与,ds:[bp]或ebp或一起使用时ds:[esp],这暗示SS是默认段。

对于MASM,ds:还需要数字绝对地址作为前缀。否则,将其视为立即目的地(不考虑方括号),而该目的地当然不是目的地。使用这样的定义CARLOC equ $-2,您将需要ds:[CARLOC]。显然,MASM不会ds在机器代码中添加无用的前缀,因此您不必担心该汇编程序。

如果需要CS / DS / ES / FS / GS / SS前缀,则标准语法是将其放在方括号之外:

MOV AL, ES:[0017H]
Run Code Online (Sandbox Code Playgroud)

AL目的地表示byte ptr操作数大小,该大小也超出了括号。例如,查看反汇编程序输出。

BYTE PTR ES:0017H成功地将代码编译到其中,

是的,这是有效的语法:方括号在某些情况下是可选的(包括绝对地址或符号)。许多人建议始终在存储操作数周围使用括号(而不是OFFSET symbol立即数),以使读者更容易理解。

如果您要使用方括号,它们会在size ptrseg:替代之后。

该程序已运行但无法正常运行

然后,您的代码中除了语法错误之外,还有其他错误。

或者,如果您尝试将其构建为Windows可执行文件:当然,将为DOS编写的代码(实模式,在整个计算机的控制下)并以32位或64位构建为代码是行不通的Windows可执行文件(保护模式或64位模式,在操作系统下为Ring 3)。系统调用ABI甚至API也完全不同:它们是不同的操作系统,而DOS API对Windows可执行文件不可用。

Michael还建议,USE32或其他指令可能会使MASM试图将您从自己身上救出来,并拒绝在应该与平面内存模型一起运行的代码中使用分段。但是,如果es:[17H]可行,那可能不是。


Mic*_*tch 5

目前还不清楚我应该回答这个问题的哪一部分。

  • 最初的错误与拼写错误有关。DS本来应该DX
  • 您使用的 MASM 版本 5.10 不支持方括号内的段和大小覆盖[]。代码如下:

    MOV     [WORD PTR DS:CARLOC],DX
    
    Run Code Online (Sandbox Code Playgroud)

    需要写成:

    MOV     WORD PTR DS:[CARLOC],DX
    
    Run Code Online (Sandbox Code Playgroud)
  • 您使用的 MASM 和 LINK 版本不会生成 COM 程序。您需要一个以前与 DOS 一起提供的名为 EXE2BIN 的程序,它可以将某些类型的 EXE 程序转换为 COM。你必须像这样运行 EXE2BIN:

    EXE2BIN progname.exe progname.com
    
    Run Code Online (Sandbox Code Playgroud)
  • 据我所知,MASM 的版本不支持简化的段指令.MODEL.CODE.DATA、 ,.STACK因此需要删除它们。


您可以修改代码以作为 EXE 程序运行,而不是使用 EXE2BIN 从 EXE 转换为 COM 程序。删除行:

    .MODEL  TINY
    .CODE
    .ORG 100h
Run Code Online (Sandbox Code Playgroud)

创建一个STACK类似于以下内容的段:

STACK SEGMENT STACK
    db 512 DUP(?)
STACK ENDS
Run Code Online (Sandbox Code Playgroud)

EXE 程序需要在程序启动时尽早初始化DS(如果需要,还可以初始化ES )。这与 COM 程序不同,其中CS=DS=ES=SS,并且不需要此类初始化。您可以添加这些行来初始化DS

    MOV     AX, CODE                ; Initialize the Code Segment
    MOV     DS, AX
Run Code Online (Sandbox Code Playgroud)

您将所有数据放入CODE段中,因此需要将DS初始化为与 相同CODE

应作为 EXE 运行的程序的最终版本是:

        TITLE   FormulaONE TURBO (256 byte game)


STACK SEGMENT STACK
    db 512 DUP(?)
STACK ENDS

CODE    SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:CODE,DS:CODE

;--------------------------------------------------------------------------
;                       ACTUAL PROGRAM BEGINS HERE
;--------------------------------------------------------------------------
START:
        MOV     AX, CODE                ; Initialize the Code Segment
        MOV     DS, AX
        MOV     BP,AX                   ; Reset score to 0 (=MOV BP,0)
        MOV     AH,06H                  ; Clear Screen and home the cursor
        CALL    SCROLL
;--------------------------------------------------------------------------
;                             MAIN GAME LOOP
;--------------------------------------------------------------------------
GAME:
        MOV     DX,1629H                ; Load CAR loc (LINE 16H, COL 29H)
CARLOC  EQU     $-2                     ; Self modifying code (CAR loc)

        CALL    MOVEIT                  ; Move cursor to DH,DL (car loc)
;--------------------------------------------------------------------------
;  Erase the car at old screen location
;--------------------------------------------------------------------------
        MOV     AL,20H                  ; Print 5 spaces
        PUSH    AX
        OUT     61H,AL                  ;   Turn off speaker (AL=00100000b)
        MOV     BL,70H                                                ;^^
        MOV     CL,5
        INT     10H

        MOV     AX,0E0AH                ; Move cursor to next line
        INT     10H

        POP     AX                      ; Print 5 more spaces
        INT     10H
;--------------------------------------------------------------------------
;  Move to new car location based on shift key status
;--------------------------------------------------------------------------
        MOV     CL,40H                  ; Get shift key status
        MOV     ES,CX                   ;   (=MOV ES,0040H)
        MOV     AL,BYTE PTR ES:[0017H]

        TEST    AL,1                    ; Right SHIFT key pressed?
        JZ      TRYLFT                  ;    No...Try left shift
        INC     DX                      ;    Yes..move car right 1 space
TRYLFT: TEST    AL,2                    ; Left SHIFT key pressed?
        JZ      KEYEND                  ;    No...done checking keys
        DEC     DX                      ;    Yes..move car left 1 space
KEYEND: MOV     WORD PTR DS:[CARLOC],DX ; Save new car location in memory
                                        ; (That is the self-modifying part)
        PUSH    DX                      ; Save car location on stack also
;--------------------------------------------------------------------------
;  Scroll the track down one line
;--------------------------------------------------------------------------
        MOV     AX,0701H                ; Scroll screen down 1 line
        CALL    SCROLL                  ;   this also sets BH=0 and BL=2
                                        ;   and homes the cursor

        MOV     CL,40                   ; Print left side of track
LMARGN  EQU     $-1                     ;   (Pointer to Left Margin)
        INT     10H

        MOV     DX,CX                   ; Find right side of track position
        ADD     DX,26                   ;   (Starting track width = 26)
TRKWID  EQU     $-1                     ;   (Pointer to Track Width)
        MOV     CL,80
        SUB     CX,DX
        CALL    MOVEIT                  ; Move cursor to right side of track
        INT     10H                     ; Print grass on right side of track
;--------------------------------------------------------------------------
;  Print the score in the lower right corner of the screen
;--------------------------------------------------------------------------
        MOV     DX,184EH                ; Screen loc 77,25 bottom right
        CALL    MOVEIT                  ; Move cursor to score location
        MOV     AX,BP                   ; Move Score to AX
        MOV     CL,8                    ; Shift score right 8 bits
        SAR     AX,CL                   ; (This makes it hard to get to Z!)
        ADD     AX,0E00H+65             ; MOV AH,0Eh & Convert score to A-Z
        INT     10H                     ; Print the score on the screen
;--------------------------------------------------------------------------
;  Check for a collision
;--------------------------------------------------------------------------
        POP     DX                      ; Restore car location from stack
        CALL    MOVEIT                  ; Move cursor under left front tire
        JNZ     PCAR                    ; Hit something? Yes... Print our
                                        ;   red car and exit the game
        PUSH    DX                      ; Save left tire position to stack
        ADD     DL,4                    ; Move cursor under right front tire
        CALL    MOVEIT                  ; Check to see if we hit something
        POP     DX                      ;    Restore our car position
        JNZ     PCAR                    ; Hit something? Yes... Print our
                                        ;   red car and exit the game
        PUSH    DX                      ; Save car position to stack
;--------------------------------------------------------------------------
;  No collision, go ahead and print our car (red)
;--------------------------------------------------------------------------
        CALL    PCAR                    ; Print our red car (CX=8)
;--------------------------------------------------------------------------
;  Slow game down by waiting for 3 vertical retraces and play sound effects
;--------------------------------------------------------------------------
        MOV     CL,3                    ; CX is delay invertical retraces
DELAY:  MOV     DX,03DAH                ; Video screen port
HERE:   IN      AL,DX                   ; Get current video status
        TEST    AL,8                    ; Check vertical retrace bit
        JNE     HERE                    ; Wait for 1 full vertical retrace
HERE2:                                  ; Turn on and off speaker...
        ADD     AL,BYTE PTR DS:[005DH]  ;   (Check command line for Q)
        DEC     AX                      ;   (which is for Quiet mode.)
        OUT     61H,AL                  ; while waiting for screen refresh
        IN      AL,DX
        TEST    AL,8
        JE      HERE2
        LOOP    DELAY                   ; Go wait for another until CX=0
;--------------------------------------------------------------------------
;  Keep track of our current score
;--------------------------------------------------------------------------
        INC     BP                      ; Count lines printed so far (score)
;--------------------------------------------------------------------------
;  Adjust size and placement of track
;--------------------------------------------------------------------------
        POP     DX                      ; Restore our car position fm stack
        MOV     AX,BP                   ; TEST AL=2 bytes, TEST BP=4 bytes

        TEST    AL,255                  ; Make track smaller each 256 lines
        JNZ     NOCHG                   ;   Go around if not time for change
        DEC     BYTE PTR DS:[TRKWID]    ;   Change width (Self-mod code!)
NOCHG:

        TEST    AL,9                    ; Make track wavy every so often
        JNZ     ENEMY                   ;  Time to go straight
        TEST    AL,128                  ;  Left or right?
        JZ      LEFT
        ADD     BYTE PTR DS:[LMARGN],2  ; -Move right 2 spaces (Self-mod!)
;        INC     DX                      ;    Make sure that enemy car
;        INC     DX                      ;      stays ON the track. (TAI)
LEFT:   DEC     BYTE PTR DS:[LMARGN]    ; -Move left 1 space   (Self-mod!)
;        DEC     DX                      ;    Make sure that enemy car
                                        ;      stays ON the track. (TAI)
;--------------------------------------------------------------------------
;  Draw an opponent car every 15 screen lines
;--------------------------------------------------------------------------
ENEMY:                                  ; Our car position is in DX register
        MOV     DH,0                    ; Make it into enemy position using
                                        ; True Artificial Intellegence (tm)
                                        ; ^    ^          ^  TAI :-)
        TEST    AL,15                   ; Every 15 lines print enemy car
        MOV     AX,OFFSET GAME          ;    Prepare for RET below
        PUSH    AX                      ;    Use RET as a jump to GAME loop
        JNZ     GOBACK                  ; Not time yet to print enemy car
;--------------------------------------------------------------------------
;                PRINT CAR AT SCREEN LOCATION "DX"
;
; On entry:  DH points to line, DL to column, CX to car graphic offset
;                                             (8 for red, 0 for blue car)
; On exit:  The proper car will be drawn.  Also, if we used CALL PCAR to
;           get here we will be returned into the program at that point.
;           If we used JNZ PCAR to get here we will be returned to the
;           DOS prompt (the game will end).
;--------------------------------------------------------------------------
PCAR:
        PUSH    BP                      ; Save our current score counter
        MOV     BP,OFFSET CAR2          ; Point to the car graphic
        ADD     BP,CX                   ;   Add offset to proper car
        SUB     BYTE PTR [BP+4],24      ; Print stripe on hood of car
        MOV     AX,1302H                ; Print the car to the screen
        PUSH    AX                      ;    AX may change in INT 10h call
        MOV     CL,5                    ;    Graphic is 5 characters wide
        PUSH    DS                      ;    It is located in the data seg
        POP     ES                      ;      but INT 10h needs that in ES
        INT     10H                     ; Print the first line of the car
        ADD     BYTE PTR [BP+4],24      ; Print cockpit and rear stripe
        POP     AX                      ; (=MOV AX,1302H)
        INC     DH                      ; Point to next line of the screen
        INT     10H                     ; Print the second line of the car
        POP     BP                      ; Restore current score counter
GOBACK: RET
CAR2:  
        DB      0DCH,70H,0DEH,71H,0D2H,1FH,0DDH,71H     ; Blue car graphic
        DB      0DCH,70H                                ;   Common tire
        DB      0DEH,74H,0D2H,4EH,0DDH,74H,0DCH,70H     ; Red car graphic
;--------------------------------------------------------------------------
;                     SCROLL SCREEN DOWN "AL" LINES
;                      (or if AH=6, clear screen)
;
; On entry:  AH must be 7, AL must be number of lines to scroll (1)
; On exit:   BH will be 0, BL will be 2 and we will fall through to
;            MOVEIT to home the cursor.             ^^^^^^^^^^^^
;--------------------------------------------------------------------------
SCROLL:
        MOV     BH,70H                  ; Use Black on Gray (road color)
        XOR     CX,CX                   ;   From UL corner (=MOV CX,0)
        MOV     DX,184FH                ;   to LR corner
        INT     10H
        MOV     BX,02                   ; Set BH to 0 and BL to 2 for use
                                        ;   when we return.
        XOR     DX,DX                   ; Now, home the cursor  (=MOV DX,0)
;--------------------------------------------------------------------------
;                  MOVE CURSOR TO SCREEN LOCATION DH,DL
;               AND SEE IF THERE IS A SPACE (TRACK) THERE
;
; On entry:  DH is screen line, DL is screen column
; On exit:   Z flag will be set/reset if there is a space character
;            under the cursor and AH will be 9 and AL will be 0DBh
;--------------------------------------------------------------------------
MOVEIT:
        MOV     AH,2                    ; Move cursor to DH,DL
        INT     10H
        MOV     AH,8                    ; Get the character under cursor
        INT     10H
        CMP     AL,20H                  ; Is it a space? (set Z flag)
        MOV     AX,09DBH                ; Set AH to 9 and AL to 0DBh for
        RET                             ;  use just after we return (don't
                                        ;  worry, Z flag will still be set)
CODE    ENDS

        END     START

Reply to "Stackoverflow question a2061"
Author
Title
Re: Stackoverflow question a2061
Language

Your paste - Paste your paste here
        TITLE   FormulaONE TURBO (256 byte game)
;==========================================================================
;      FormulaONE TURBO Copyright 1995, 1996, 1998 by David S. Issel
;                          all rights reserved.
;
;                      Written using Turbo Assembler
;
;                     To assemble use:  TASM F1-TURBO
;                         To link use:  TLINK /x/t F1-TURBO
;
; For Microsoft Macro Assembler 6.0 use:  ML /AT F1-TURBO.ASM
;
;
;               To run FormulaONE use:  F1-TURBO
;     To run FormulaONE without sound:  F1-TURBO Q
;
;  Use left and right shift keys to control your car                  __,        
;  at bottom of screen.  Try not to run into anything       _ _.--'-n_/          
;  for as long as you can.                                -(_)------(_)=         
;==========================================================================
        .MODEL  TINY
        .CODE
CODE    SEGMENT BYTE PUBLIC 'CODE'
        ASSUME  CS:CODE,DS:CODE
        ORG     0100H                   ; This will be a COM file
;--------------------------------------------------------------------------
;                       ACTUAL PROGRAM BEGINS HERE
;--------------------------------------------------------------------------
START:
        MOV     BP,AX                   ; Reset score to 0 (=MOV BP,0)
        MOV     AH,06H                  ; Clear Screen and home the cursor
        CALL    SCROLL
;--------------------------------------------------------------------------
;                             MAIN GAME LOOP
;--------------------------------------------------------------------------
GAME:
        MOV     DX,1629H                ; Load CAR loc (LINE 16H, COL 29H)
CARLOC  EQU     $-2                     ; Self modifying code (CAR loc)

        CALL    MOVEIT                  ; Move cursor to DH,DL (car loc)
;--------------------------------------------------------------------------
;  Erase the car at old screen location
;--------------------------------------------------------------------------
        MOV     AL,20H                  ; Print 5 spaces
        PUSH    AX
        OUT     61H,AL                  ;   Turn off speaker (AL=00100000b)
        MOV     BL,70H                                                ;^^
        MOV     CL,5
        INT     10H

        MOV     AX,0E0AH                ; Move cursor to next line
        INT     10H

        POP     AX                      ; Print 5 more spaces
        INT     10H
;--------------------------------------------------------------------------
;  Move to new car location based on shift key status
;--------------------------------------------------------------------------
        MOV     CL,40H                  ; Get shift key status
        MOV     ES,CX                   ;   (=MOV ES,0040H)
        MOV     AL,[BYTE PTR ES:0017H]

        TEST    AL,1                    ; Right SHIFT key pressed?
        JZ      TRYLFT                  ;    No...Try left shift
        INC     DX                      ;    Yes..move car right 1 space
TRYLFT: TEST    AL,2                    ; Left SHIFT key pressed?
        JZ      KEYEND                  ;    No...done checking keys
        DEC     DX                      ;    Yes..move car left 1 space
KEYEND: MOV     [WORD PTR DS:CARLOC],DX ; Save new car location in memory
                                        ; (That is the self-modifying part)
        PUSH    DX                      ; Save car location on stack also
;--------------------------------------------------------------------------
;  Scroll the track down one line
;--------------------------------------------------------------------------
        MOV     AX,0701H                ; Scroll screen down 1 line
        CALL    SCROLL                  ;   this also sets BH=0 and BL=2
                                        ;   and homes the cursor

        MOV     CL,40                   ; Print left side of track
LMARGN  EQU     $-1                     ;   (Pointer to Left Margin)
        INT     10H

        MOV     DX,CX                   ; Find right side of track position
        ADD     DX,26                   ;   (Starting track width = 26)
TRKWID  EQU     $-1                     ;   (Pointer to Track Width)
        MOV     CL,80
        SUB     CX,DX
        CALL    MOVEIT                  ; Move cursor to right side of track
        INT     10H                     ; Print grass on right side of track
;--------------------------------------------------------------------------
;  Print the score in the lower right corner of the screen
;--------------------------------------------------------------------------
        MOV     DX,184EH                ; Screen loc 77,25 bottom right
        CALL    MOVEIT                  ; Move cursor to score location
        MOV     AX,BP                   ; Move Score to AX
        MOV     CL,8                    ; Shift score right 8 bits
        SAR     AX,CL                   ; (This makes it hard to get to Z!)
        ADD     AX,0E00H+65             ; MOV AH,0Eh & Convert score to A-Z 
        INT     10H                     ; Print the score on the screen
;--------------------------------------------------------------------------
;  Check for a collision
;--------------------------------------------------------------------------
        POP     DX                      ; Restore car location from stack
        CALL    MOVEIT                  ; Move cursor under left front tire
        JNZ     PCAR                    ; Hit something? Yes... Print our
                                        ;   red car and exit the game
        PUSH    DX                      ; Save left tire position to stack
        ADD     DL,4                    ; Move cursor under right front tire
        CALL    MOVEIT                  ; Check to see if we hit something
        POP     DX                      ;    Restore