最近,我正在编写程序集,并且我编写的程序在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
(更新: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 ptr和seg:替代之后。
该程序已运行但无法正常运行
然后,您的代码中除了语法错误之外,还有其他错误。
或者,如果您尝试将其构建为Windows可执行文件:当然,将为DOS编写的代码(实模式,在整个计算机的控制下)并以32位或64位构建为代码是行不通的Windows可执行文件(保护模式或64位模式,在操作系统下为Ring 3)。系统调用ABI甚至API也完全不同:它们是不同的操作系统,而DOS API对Windows可执行文件不可用。
Michael还建议,USE32或其他指令可能会使MASM试图将您从自己身上救出来,并拒绝在应该与平面内存模型一起运行的代码中使用分段。但是,如果es:[17H]可行,那可能不是。
目前还不清楚我应该回答这个问题的哪一部分。
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
| 归档时间: |
|
| 查看次数: |
74 次 |
| 最近记录: |