assembly - 在 8086 中通过 TASM 使用 Pusha 和 Popa

标签 assembly x86-16 tasm

如何使用 tasm 编译器在程序集 8086 中使用 Pusha/popa?我在网上读到,因为 Pusha 和 Popa 是另一种类型的程序集 (.286),所以我无法使用它,但有一种方法可以告诉编译器包含这些命令。

我现在的代码:

IDEAL
MODEL small
STACK 100h
DATASEG
CODESEG
proc OpenFile
            push bp
            mov bp, sp
            pusha
            mov dx, [bp + 6]    ;Get File Name Offset
            mov si, [bp + 4]    ;Get File Handler
            mov ah, 3Dh
            xor al, al
            int 21h
            jc openerror
            mov [word ptr si], ax
            popa
            pop bp
            ret 4
openerror:  lea dx, [ErrorMsg]
            mov ah, 9h
            int 21h
            popa
            pop bp
            ret 4
endp OpenFile

我得到的错误:

Illegal instruction for currently selected processor(s)

有人知道如何做到这一点吗?

最佳答案

在文件的第一行写入 .286:

.286
IDEAL
MODEL small
STACK 100h
etc.

编辑:我已经编写了执行此类操作的程序,它们在这里:

    ;CONSTANTS: {
        ;ACTIONS: {
            READ            EQU 0
            WRITE           EQU 1
            READ&WRITE      EQU 2   ;NOT USABLE AS AN ACTION
        ;}

        ;RELATIVE TO: {
            START_OF_FILE   EQU 0
            CURRENT_POINTER EQU 1
            END_OF_FILE     EQU 2
        ;}
    ;}

    ;*********************************************************************************
    ;*********************************************************************************

    PROC FILE_OPEN
    ;INPUT: OFFSET OF FILE NAME
    ;OUTPUT: FILE HANDLE (ALL THATS LEFT IS TO "POP" IT INTO A VARIABLE/REGISTER)

    ;EXAMPLE:
        ;PUSH OFFSET FILE_NAME
        ;CALL FILE_OPEN
        ;POP [FILE_HANDLE]

    ;{  
        ;START_PROC {
            PUSH BP
            MOV  BP, SP

            _NAME  EQU [WORD PTR BP + 4] 

            PUSH AX BX DX
        ;}

        ;CODE{
            MOV DX, _NAME

            MOV AH, 3Dh
            MOV AL, READ&WRITE

            INT 21h
            JC  @@END_PROC

            MOV BX, HANDLE
            MOV [BX], AX 
        ;}

        @@END_PROC: ;{
            POP DX BX AX
            POP BP
            RET 
        ;}
    ;}
    ENDP FILE_OPEN

    ;*********************************************************************************
    ;*********************************************************************************

    PROC FILE_READ_OR_WRITE
    ;{
        ;INPUT: READ OR WRITE, FILE HANDLE, BUFFER OFFSET, NUMBER OF BYTES TO READ/WRITE
        ;OUTPUT: THE DATA IS LOADED FROM THE FILE TO THE BUFFER (IF READ), OR THE DATA IS LOADED FROM THE BUFFER TO THE FILE (WRITE)

        ;START PROC {
            PUSH BP
            MOV  BP, SP

            ACTION    EQU [WORD PTR BP + 10]    ;READ OR WRITE (CONSTANT)
            BUFFER    EQU [WORD PTR BP + 8]     ;BUFFER OFFSET
            NUM_BYTES EQU [WORD PTR BP + 6]     ;NUMBER OF BYTES DO LOAD
            HANDLE    EQU [WORD PTR BP + 4]     ;FILE HANDLE


            PUSH AX BX CX DX
        ;}

        ;SET UP PARAMS {
            MOV BX, HANDLE
            MOV CX, NUM_BYTES
            MOV DX, BUFFER

            CMP ACTION, WRITE
            JZ  @@WRITE
        ;}

        @@READ: ;{
            MOV AX, 3F00h
            INT 21h
            JMP @@END_PROC
        ;}

        @@WRITE: ;{
            MOV AX, 4000h
            INT 21h 
        ;}

        @@END_PROC: ;{
            POP DX CX BX AX BP
            RET 8
        ;}
    ;}
    ENDP FILE_READ_OR_WRITE

    ;*********************************************************************************
    ;*********************************************************************************

    PROC FILE_CLOSE
    ;INPUT: FILE HANDLE
    ;OUTPUT: THE FILE IS CLOSED
    ;{
        ;START PROC {
            PUSH BP
            MOV  BP, SP
            HANDLE EQU [BP + 4] ;FILE HANDLE

            PUSH AX BX
        ;}

        ;CODE {
            MOV AH, 3Eh
            MOV BX, HANDLE
            INT 21h
        ;}

        @@END_PROC: ;{
            POP BX AX
            POP BP
            RET 2
        ;}
    ;}
    ENDP FILE_CLOSE

    ;*********************************************************************************
    ;*********************************************************************************

    PROC FILE_UPDATE_POINTER
    ;INPUT: RELATIVE_TO(MOVING THE POINTER RELATIVE TO [START_OF_FILE, CURRENT_POINTER, END_OF_FILE]
    ;INPUT: NUM_BYTES(_1), MOVES THE POINTER NUM1:NUM SPOTS (SIGNED DWORD) WHERE POSITIVE = RIGHT AND NEGATIVE = LEFT
;INPUT: FILE HANDLE

    ;OUTPUT: UPDATES THE FILE POINTER
    ;{
        ;START PROC {
            PUSH BP
            MOV  BP, SP

            RELATIVE_TO EQU [BP + 10]   ;CONSTANT
            NUM_BYTES_1 EQU [BP + 8]    ;HIGH ORDER WORD
            NUM_BYTES   EQU [BP + 6]    ;LOW  ORDER WORD
            HANDLE      EQU [BP + 4]    ; FILE HANDLE

            PUSH AX BX CX DX
        ;}

        ;CODE {
            MOV AX, RELATIVE_TO
            MOV AH, 42h
            MOV BX, HANDLE
            MOV CX, NUM_BYTES_1
            MOV DX, NUM_BYTES
            INT 21h     
        ;}

        @@END_PROC: ;{
            POP DX CX BX AX
            POP BP
            RET 8
        ;}
    ;}
    ENDP FILE_UPDATE_POINTER

关于assembly - 在 8086 中通过 TASM 使用 Pusha 和 Popa,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36902960/

相关文章:

assembly - 将两个无符号 16 位值相乘,不使用乘法或除法指令 [8086 汇编]

c - 为什么要在函数序言/结语中使用 ebp?

组件(TASM): print the sum of certain bits in bytes

file - 当我使用 int 21h 函数时,我的 asm 代码写入垃圾字节

assembly - x86 子指令操作码混淆

performance - 组装一些与 nasm 宏不相符的代码

gcc - 使用 gcc 使用 YMM 指令添加数组

assembly - "int 21h"在汇编中是什么意思?

assembly - 在 8086 中连接两个给定的字符串 + MOVSB 不起作用

assembly - 汇编器无法找到现有文件