Why isn't my code working when adding .386?
Asked Answered
G

1

5

As explained in the title, I need to make this code able to do the same things it do using just 16bit but adding .386 to the code so I can use 32bit registers. But when I add the .386 now my code isn't printing anything, any idea how I can fix this. Is it something wrong with my mov as, @data or do I need to add something else? I am using 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
Gibe answered 26/6, 2020 at 21:11 Comment(7)
Why is your .loop1 loop using si when you haven't initialized si at that point?Hexahydrate
You right there, but it still is using si as if it had 0Gibe
Still dont know how to turn it to 32 bitGibe
What happens if you put .386 after .model small rather than before so change it to .model small .386Covalence
Oh wasnt expecting that, thanks its working now, just one more question, now if I use 32bit register they should work fine right? Even if I dont change the mov data and the 16 bit registers?Gibe
Yes, you will be able to use the 32-bit registers in the 16-bit code.Covalence
Related questions: #47942199 and #26829091Hexahydrate
C
9

The MASM 6.1 documentation is a good resource for writing real-mode segmented code (non-FLAT models). Even though you are using TASM, the MASM documentation is still a good reference. What you are encountering is a side effect of a rather subtle way in which code is generated depending on where you place the .386 directive relative to the .MODEL directive. This subtle behaviour is documented in the section Setting Segment Word Sizes (80386/486 Only):

Setting Segment Word Sizes (80386/486 Only)

The use type in the SEGMENT directive specifies the segment word size on the 80386/486 processors. Segment word size determines the default operand and address size of all items in a segment. The size attribute can be USE16, USE32, or FLAT. If you specify the .386 or .486 directive before the .MODEL directive, USE32 is the default. This attribute specifies that items in the segment are addressed with a 32-bit offset rather than a 16-bit offset. If .MODEL precedes the .386 or .486 directive, USE16 is the default. To make USE32 the default, put .386 or .486 before .MODEL. You can override the USE32 default with the USE16 attribute, or vice versa.

What you need to be careful about is where you place .386. You have placed it before .model thus the assembler is assuming that all the sections are USE32 by default. This means all the instructions that are being generated are encoded with the assumption the processor is running in 32-bit mode. 32-bit encoded instruction do not run properly in 16-bit code and is the cause of your program failure.

You are writing code that will run in 16-bit real-mode (possibly using 386 instructions and registers) so I believe you will want to ensure USE16 is the default when using the .code and .data directives. To get the behaviour you want you have to make this change:

.386
.model small

To:

.model small
.386
Covalence answered 26/6, 2020 at 21:52 Comment(2)
Wow - you gotta love the x86. And all of its assemblers!Sludge
@ErikEidt: It's fully possible to not love any of the MASM-like 16-bit DOS assemblers and their weird directive quirks for specifying default operand-size (CPU mode) vs. whether to allow CPU features like push immediate (186) or 32-bit operand-size via prefixes. :PHanako

© 2022 - 2024 — McMap. All rights reserved.