Assembly 为什么不是';添加.386时我的代码不起作用吗?

Assembly 为什么不是';添加.386时我的代码不起作用吗?,assembly,x86,32-bit,tasm,real-mode,Assembly,X86,32 Bit,Tasm,Real Mode,正如在标题中所解释的,我需要使这段代码能够使用16位完成与它相同的事情,但是在代码中添加.386,这样我就可以使用32位寄存器。但是当我现在添加.386时,我的代码没有打印任何内容,我不知道如何解决这个问题。我的mov as、@data有什么问题吗?还是需要添加其他内容?我在用TASM TITLE Programa de prueba(prueba.asm) .386 .model small .stack .data escog

正如在标题中所解释的,我需要使这段代码能够使用16位完成与它相同的事情,但是在代码中添加.386,这样我就可以使用32位寄存器。但是当我现在添加.386时,我的代码没有打印任何内容,我不知道如何解决这个问题。我的mov as、@data有什么问题吗?还是需要添加其他内容?我在用TASM

TITLE Programa de prueba(prueba.asm)
.386                              
.model small
.stack 

.data

escoga db 10,13,7, 'Escoga la operacion: 1. x and y, 2. x or y, 3. not x, 4. x xor y, 5. terminar:  
', '$'

digite1 db 10,13,7, 'Digite el primer numero hexadecimal: ', '$'
digite2 db 10,13,7, 'Digite el segundo numero hexadecimal: ', '$'
Yval db "Enter Y hexadecimal value: ",0
resultStr db "The result is: ",0
result db ?
x db 8 DUP(' '),'$'
y db 8 DUP(' '),'$'
num db 1 DUP(0),'$'

.code
main proc
    mov ax, @data
    mov ds, ax

.loop1:
    cmp si, 82 
    je .done1 
    mov ah, 0Eh 
    mov al, escoga[SI] 
    mov bh, 00h 
    int 10h 
    inc si 
    jmp .loop1

.done1:
    mov si, 0
    mov di, 0
.inp1:
    cmp si, 1 
    je .ext1 
    mov ah, 00h 
    int 16h 
    inc si 
    inc di 
    jmp .modi1 

.modi1:
    mov num[di], al 
    mov ah, 0Eh 
    mov al, num[di] 
    mov bh, 00h 
    int 10h 
    jmp .inp1 

.ext1:
    mov si, 0
.ext2:
    cmp si, 2
    je .salir
    mov ah, 0Eh 
    mov al, num[SI] 
    inc si 
    jmp .ext2

.salir:
    cmp num[SI-1], '5'
    jge .term
    jmp .term2
    
.term2:
    mov si, 0
 
.loop2:
    cmp si, 40
    je .done2
    mov ah, 0Eh 
    mov al, digite1[SI] 
    mov bh, 00h 
    int 10h 
    inc si 
    jmp .loop2

.done2:
    mov si, 0
    mov di, 0

.inp2:
    cmp si, 8 
    je .ext3 
    mov ah, 00h 
    int 16h 
    inc si 
    inc di 
    jmp .modi2 

.modi2:
    mov x[di], al 
    mov ah, 0Eh 
    mov al, x[di] 
    mov bh, 00h 
    int 10h 
    jmp .inp2

.ext3:
    mov si, 0 
    mov di, 0

.loop3:
    cmp si, 41
    je .done3
    mov ah, 0Eh 
    mov al, digite2[SI] 
    mov bh, 00h 
    int 10h 
    inc si 
    jmp .loop3

.done3:
    mov si, 0
    mov di, 0

.inp3:
    cmp si, 8 
    je .ext4 
    mov ah, 00h 
    int 16h 
    inc si 
    inc di 
    jmp .modi3 

.modi3:
    mov y[di], al 
    mov ah, 0Eh 
    mov al, y[di] 
    mov bh, 00h 
    int 10h 
    jmp .inp3

.ext4:
    mov si, 0 
    mov di, 0    

.term:
.exit
 
main endp  

end main
是编写实模式分段代码(非平面模型)的良好资源。即使您正在使用TASM,MASM文档仍然是一个很好的参考。您所遇到的是一种相当微妙的方式的副作用,这种方式根据您放置
.386
指令相对于
.MODEL
指令的位置来生成代码。这种微妙的行为记录在设置段字长(仅80386/486)一节中:

设置段字大小(仅80386/486)

段指令中的使用类型指定段字大小 在80386/486处理器上。段字大小决定默认值 段中所有项的操作数和地址大小。大小属性 可以使用16、32或平面如果指定.386或.486 .MODEL指令之前的指令,默认为USE32。这 属性指定段中的项使用 32位偏移量而不是16位偏移量。如果.MODEL在.386之前 或.486指令,USE16为默认值。要使USE32为默认值, 将.386或.486放在.MODEL之前。您可以覆盖USE32默认值 使用USE16属性,反之亦然

您需要注意的是放置
.386
的位置。您已将其放置在
.model
之前,因此汇编程序假定默认情况下所有部分都是
USE32
。这意味着所有正在生成的指令都是在假定处理器以32位模式运行的情况下进行编码的。32位编码指令不能在16位代码中正常运行,这是导致程序失败的原因

您编写的代码将以16位实模式运行(可能使用386条指令和寄存器),因此我相信您希望确保在使用
.code
.data
指令时,
USE16
是默认值。要获得您想要的行为,您必须进行以下更改:

.386
.model small
致:


为什么你的
.loop1
循环在你还没有初始化
si
时使用
si
呢?你就在那里,但它仍然在使用si,就好像它有0如果你把
.386
放在
之后会发生什么事。把model small
改成
。model small
.386是的,您将能够在16位代码中使用32位寄存器。相关问题:哇,您一定喜欢x86。还有所有的汇编程序@ErikEidt:完全有可能不喜欢任何类似MASM的16位DOS汇编程序,也不喜欢它们在指定默认操作数大小(CPU模式)方面的奇怪指令怪癖,而不是通过前缀允许CPU功能,如立即推送(186)或32位操作数大小P
.model small
.386