Invalid fix up found,type 0x0001 - c

I have these 3 .asm files and 1 c file.
Exp3_1.asm
NAME MAIN
.386
.MODEL FLAT, C
printf PROTO :ptr sbyte, :VARARG
scanf PROTO :ptr sbyte, :VARARG
includelib libcmt.lib
includelib legacy_stdio_definitions.lib
;DATA SEGMENT USE16 PARA PUBLIC 'DATA'
CRLF MACRO ;�س�
invoke printf, offset FMT, addr CRLFT
ENDM
PRINT MACRO A ;��ӡ����
invoke printf, offset FMT, addr A
ENDM
READ MACRO A ;��ȡ����
invoke scanf, offset FMT, addr A
ENDM
SHOWVALUE MACRO A, B
PRINT A
MOV AX, B[EBX]
LEA ESI, VALUE
CALL F2TO10
MOV BYTE PTR [ESI], 0DH
MOV BYTE PTR [ESI+1], 0AH
MOV BYTE PTR [ESI+2], 0
PRINT VALUE
ENDM
CHANGEVALUE MACRO A, B
LOCAL LL
LL: PRINT A
MOV AX, B[EBX]
LEA ESI, VALUE
CALL F2TO10
MOV BYTE PTR [ESI], 0
PRINT VALUE
PRINT SEPARATOR
CALL GETVALUE
CMP DI, 1
JE LL
MOV B[EBX], DX
ENDM
.DATA
MENUT DB 'Please Enter a Number(1~9):', 0
INNAMET DB 'User Name:', 0
WRONGNAMET DB 'Invalid User Name', 0
INNAME DB 10 DUP(0)
INPWDT DB 'Password:', 0
WRONGPWDT DB 'Invalid Password', 0
INPWD DB 10 DUP(0)
LOGINST DB 'Login in', 0
INGOODT DB 'Good Name:', 0
WRONGGOODT DB 'Invalid Good Name', 0
INGOOD DB 10 DUP(0)
CHANGEGOODT DB 'Good Selected', 0
NOGOODT DB 'No Goods', 0
SELLGOODT DB 'Good Sold', 0
NOTSELECTEDT DB 'No Goods Selected', 0
UPDATEPRIOT DB 'Priority Updated', 0
NOTBOSST DB 'Authrity Denied', 0
BPRICET DB 'Buying Price:', 0
SPRICET DB 'Selling Price:', 0
BAMOUNTT DB 'Buying Amount:', 0
SAMOUNTT DB 'Selling Amount:', 0
VALUE DB 8 DUP(0)
SEPARATOR DB '->',0
BNAME DB 'GUSHIYU', 0 ;�ϰ�����
BPASS DB '153426', 0 ;����
AUTH DB 0 ;��ǰ��¼״̬��0��ʾ�˿�״̬
GOOD DD 0 ;��ǰ�����Ʒ��ַ
N EQU 30
SNAME DB 'SHOP', 0 ;�������ƣ���0����
GA1 DB 'PEN', 7 DUP(0), 10 ;��Ʒ���Ƽ��ۿ�
DW 35, 56, 70, 25, ? ;�����ۣ����ۼۣ����������������������Ƽ���
GA2 DB 'BOOK', 6 DUP(0), 9 ;��Ʒ���Ƽ��ۿ�
DW 12, 30, 25, 5, ? ;�Ƽ��Ȼ�δ����
GAN DB N-2 DUP( 'TempValue' , 0, 8, 15, 0, 20, 0, 30, 0, 2, 0, ?, ?)
;������ƷĬ��ֵ
CRLFT DB 0DH, 0AH, 0
A DB 'A', 0 ;������
B DB 'B', 0
FMT DB '%s', 0
FMTC DB '%c', 0
CHAR DB 0
.CODE
;START: MOV AX, DATA ;����ʼ
;MOV DS, AX
;MENU: PRINT MENUT ;���˵�
;MOV AH, 01H
;INT 21H
;CRLF
;CMP AL, '1'
;JE CF1
;CMP AL, '2'
;JE CF2
;CMP AL, '3'
;JE CF3
;CMP AL, '4'
;JE CF4
;CMP AL, '6'
;JE CF6
;CMP AL, '8'
;JE CF8
;CMP AL, '9'
;JE OVER
;JMP MENU
;CF1: CALL FUNC1
;JMP MENU
;CF2: CALL FUNC2
;JMP MENU
;CF3: CALL FUNC3
;JMP MENU
;CF4: CALL FUNC4
;JMP MENU
;CF6: CALL FUNC6
;JMP MENU
;CF8: CALL FUNC8
;JMP MENU
FUNC1 PROC ;����1
;LOCAL CHECK_USER, CHECK_PWD, WRONG_NAME, WRONG_PWD, LOGIN_S
PRINT INNAMET
READ INNAME
CRLF
LEA EDI, INNAME
LEA ESI, BNAME
CHECK_USER: ;���ֽڱȽ��û���
MOV AL, [EDI]
CMP AL, [ESI]
JNE WRONG_NAME
INC EDI
INC ESI
CMP AL, 0
JNZ CHECK_USER
PRINT INPWDT
READ INPWD
CRLF
LEA EDI, INPWD
LEA ESI, BPASS
CHECK_PWD: ;���ֽڱȽ�����
MOV AL, [EDI]
CMP AL, [ESI]
JNE WRONG_PWD
INC EDI
INC ESI
CMP AL, 0
JNZ CHECK_PWD
JMP LOGIN_S
WRONG_NAME:
PRINT WRONGNAMET
CRLF
RET
WRONG_PWD:
PRINT WRONGPWDT
CRLF
RET
LOGIN_S: ;��½�ɹ�
MOV AUTH, 1
PRINT LOGINST
CRLF
RET
FUNC1 ENDP
FUNC2 PROC ;����2
;LOCAL CHECK_GOOD, CHECK_NAME, WRONG_GOOD, CHANGE_GOOD
PRINT INGOODT
READ INGOOD
CRLF
MOV EAX, -1
CHECK_GOOD: ;ѡ����һ���Ƚ���Ʒ
INC EAX
CMP EAX, 30
JE WRONG_GOOD
MOV ECX, EAX
IMUL ECX, 21
ADD ECX, OFFSET GA1
MOV ESI, ECX
LEA EDI, INGOOD
CHECK_NAME: ;�Ƚ���Ʒ��
MOV BL, [EDI]
CMP BL, [ESI]
JNE CHECK_GOOD
INC EDI
INC ESI
CMP BL, 0
JNZ CHECK_NAME
JMP CHANGE_GOOD
WRONG_GOOD:
PRINT WRONGGOODT
CRLF
RET
CHANGE_GOOD: ;����ѡ����Ʒ
MOV EBX, EAX
IMUL EBX, 21
ADD EBX, OFFSET GA1
MOV GOOD, EBX
PRINT CHANGEGOODT
CRLF
SHOWVALUE BPRICET, 11
SHOWVALUE SPRICET, 13
SHOWVALUE BAMOUNTT, 15
SHOWVALUE SAMOUNTT, 17
RET
FUNC2 ENDP
FUNC3 PROC ;����3
MOV EBX, GOOD
CMP EBX, 0
JE NO_SELECTED
MOV AX, 15[EBX]
MOV DX, 17[EBX]
CMP AX, DX
JNE SELL_GOOD
PRINT NOGOODT
CRLF
RET
SELL_GOOD:
INC DX
MOV 17[EBX], DX
PRINT SELLGOODT
CRLF
CALL FUNC4
RET
NO_SELECTED:
PRINT NOTSELECTEDT
CRLF
RET
FUNC3 ENDP
FUNC4 PROC ;����4
;LOCAL COMPUTE_PRIO, COMPUTE_OVER
PUSH EBP
MOV EBP, -1
PRINT UPDATEPRIOT
CRLF
COMPUTE_PRIO:
INC EBP
CMP EBP, 30
JE COMPUTE_OVER
LEA ESI, GA1
MOV ECX, EBP
IMUL ECX, 21
ADD ESI, ECX
MOV EBX, ESI
ADD EBX, 13
MOV AX, [EBX-2]
MOV BX, [EBX]
MOVSX EAX, AX
MOVSX EBX, BX
MOV EDI, 128
IMUL EDI
IDIV EBX
MOV ECX, EAX
MOV EBX, ESI
ADD EBX, 15
MOV AX, [EBX+2]
MOV BX, [EBX]
MOVSX EAX, AX
MOVSX EBX, BX
IMUL EDI
MOV EDI, 2
IDIV EDI
MOV EDX, 0
IDIV EBX
ADD EAX, ECX
MOV EBX, ESI
ADD EBX, 19
MOV [EBX], AX
JMP COMPUTE_PRIO
COMPUTE_OVER:
POP EBP
RET
FUNC4 ENDP
FUNC8 PROC ;����8
;LOCAL GET_LETTER, IS_NUM, SHOW_OVER
PUSH BP
MOV BP, 4
MOV BX, CS
GET_LETTER:
MOV CL, 4;
ROL BX, CL
MOV DL, BL
AND DL, 0FH
CMP DL, 0AH
JB IS_NUM
ADD DL, 07H
IS_NUM: ADD DL, 30H
invoke printf, offset FMTC, DL
DEC BP
JZ SHOW_OVER
JMP GET_LETTER
SHOW_OVER:
CRLF
POP BP
RET
FUNC8 ENDP
F2TO10 PROC
PUSH BX
PUSH CX
PUSH DX
MOV BX, 10
XOR CX, CX
LOP1: XOR DX, DX
DIV BX
PUSH DX
INC CX
OR EAX, EAX
JNZ LOP1
LOP2: POP AX
CMP AL, 10
JB L1
ADD AL, 7
L1: ADD AL, 30H
MOV [ESI], AL
INC ESI
DEC CX
JNZ LOP2
POP DX
POP CX
POP BX
RET
F2TO10 ENDP
FUNC6 PROC
CMP AUTH, 0
JE NOT_BOSS
CMP GOOD, 0
JE NOT_SELECTED
MOV EBX, GOOD
CHANGEVALUE BPRICET, 11
CHANGEVALUE SPRICET, 13
CHANGEVALUE BAMOUNTT, 15
CHANGEVALUE SAMOUNTT, 17
RET
NOT_SELECTED:
PRINT NOTSELECTEDT
CRLF
RET
NOT_BOSS:
PRINT NOTBOSST
CRLF
RET
FUNC6 ENDP
GETVALUE PROC
PUSH AX
PUSH CX
XOR DI, DI
XOR CX, CX
XOR DL, DL
PUSH DX
LOOP1: invoke scanf, offset FMTC, ADDR CHAR
POP DX
MOV AL, CHAR
CMP AL, 0DH
JE RETURN
CMP AL, 0AH
JE RETURN
CMP AL, '0'
JB ERR
CMP AL, '9'
JA ERR
SUB AL, '0'
MOV CL, AL
MOV AX, DX
MOV DX, 10
MUL DX
ADD AX, CX
MOV AH, 0
MOV DX, AX
PUSH DX
JMP LOOP1
ERR: CRLF
MOV DI, 1
POP CX
POP AX
RET
RETURN: POP CX
POP AX
RET
GETVALUE ENDP
END
;END START
func6.asm
NAME FUNC6
PUBLIC FUNC6
EXTERN F2TO10:NEAR, NOTSELECTEDT:BYTE, NOTBOSST:BYTE, BPRICET:BYTE, SPRICET:BYTE, BAMOUNTT:BYTE, SAMOUNTT:BYTE, VALUE:BYTE, SEPARATOR:BYTE, AUTH:BYTE, GOOD:WORD, CRLFT:BYTE
PRINT MACRO A
LEA DX, A
MOV AH, 09H
INT 21H
ENDM
CRLF MACRO
LEA DX, CRLFT
MOV AH, 09H
INT 21H
ENDM
CHANGEVALUE MACRO A, B
LOCAL C
C: PRINT A
MOV AX, B[BX]
LEA SI, VALUE
CALL F2TO10
MOV BYTE PTR [SI], '$'
PRINT VALUE
PRINT SEPARATOR
CALL GETVALUE
CMP DI, 1
JE C
MOV B[BX], DX
ENDM
CODE SEGMENT USE16 PARA PUBLIC 'CODE'
ASSUME CS:CODE
FUNC6 PROC
CMP AUTH, 0
JE NOT_BOSS
CMP GOOD, 0
JE NOT_SELECTED
MOV BX, GOOD
CHANGEVALUE BPRICET, 11
CHANGEVALUE SPRICET, 13
CHANGEVALUE BAMOUNTT, 15
CHANGEVALUE SAMOUNTT, 17
RET
NOT_SELECTED:
PRINT NOTSELECTEDT
CRLF
RET
NOT_BOSS:
PRINT NOTBOSST
CRLF
RET
FUNC6 ENDP
GETVALUE PROC
PUSH AX
PUSH CX
XOR DI, DI
XOR CX, CX
XOR DX, DX
LOOP1: MOV AH, 01H
INT 21H
CMP AL, 0DH
JE RETURN
CMP AL, 0AH
JE RETURN
CMP AL, '0'
JB ERR
CMP AL, '9'
JA ERR
SUB AL, '0'
MOV CL, AL
MOV AX, DX
MOV DX, 10
MUL DX
ADD AX, CX
MOV DX, AX
JMP LOOP1
ERR: CRLF
MOV DI, 1
POP CX
POP AX
RET
RETURN: POP CX
POP AX
RET
GETVALUE ENDP
CODE ENDS
END
F2TO10.asm
NAME F2TO10
PUBLIC F2TO10
.386
CODE SEGMENT USE16 PARA PUBLIC 'CODE'
ASSUME CS:CODE
F2TO10 PROC
PUSH BX
PUSH CX
PUSH DX
MOV BX, 10
XOR CX, CX
LOP1: XOR DX, DX
DIV BX
PUSH DX
INC CX
OR EAX, EAX
JNZ LOP1
LOP2: POP AX
CMP AL, 10
JB L1
ADD AL, 7
L1: ADD AL, 30H
MOV [SI], AL
INC SI
LOOP LOP2
POP DX
POP CX
POP BX
RET
F2TO10 ENDP
CODE ENDS
END
main.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
extern void FUNC1();
extern void FUNC2();
extern void FUNC3();
extern void FUNC4();
extern void FUNC6();
extern void FUNC8();
int main()
{
int op = 0;
while (op != 9)
{
printf("SHOP:MY SHOP\n");
printf("---------------------------------------------\n");
printf("1.Login in\n2.Select good\n3.Buy good\n4.Update recommendation\n6.Update good\n8.Show CS\n9.Exit\n");
printf("---------------------------------------------\n");
printf("Please Enter a Number:");
scanf("%d", &op);
printf("*********************************************\n");
switch (op)
{
case 1:
FUNC1();
break;
case 2:
FUNC2();
break;
case 3:
FUNC3();
break;
case 4:
FUNC4();
break;
case 6:
getchar();
FUNC6();
break;
case 8:
FUNC8();
break;
default:
break;
}
printf("*********************************************\n");
system("pause");
system(("cls"));
}
return 0;
}
I am creating the project using visual studio 2019 and masm32 as include path. When trying to compile and create object files, there are no errors, but when it is a time to link all .obj files, i get this error:
Error LNK1190 invalid fixup found, type 0x0001 Lab3 C:\Users\Blaise\source\repos\Lab3\FUNC6.obj
How can i solve this problem? is it because of older link.exe file? i am using link.exe version 5.12

Related

Input and print an array of strings in Assembly 8086

I am trying to make a 8086 program in which I input an array of string and then the program prints them. But the program prints only the 1st characters of input strings and jumbled text.
This is the code where I attempted to do it.
data segment
; Definicija podataka
poruka1 DB "Input array length: $"
strN DB " "
N DW 0
poruka2 DB "Input string: $"
strM DB " "
niz1 DB 16 dup(?)
ends
; Deficija stek segmenta
stek segment stack
dw 128 dup(0)
ends
; Ucitavanje znaka bez prikaza i cuvanja
keypress macro
push ax
mov ah, 08
int 21h
pop ax
endm
; Isis stringa na ekran
writeString macro s
push ax
push dx
mov dx, offset s
mov ah, 09
int 21h
pop dx
pop ax
endm
; Kraj programa
krajPrograma macro
mov ax, 4c02h
int 21h
endm
code segment
; Novi red
novired proc
push ax
push bx
push cx
push dx
mov ah,03
mov bh,0
int 10h
inc dh
mov dl,0
mov ah,02
int 10h
pop dx
pop cx
pop bx
pop ax
ret
novired endp
; Ucitavanje stringa sa tastature
; Adresa stringa je parametar na steku
readString proc
push ax
push bx
push cx
push dx
push si
mov bp, sp
mov dx, [bp+12]
mov bx, dx
mov ax, [bp+14]
mov byte [bx] ,al
mov ah, 0Ah
int 21h
mov si, dx
mov cl, [si+1]
mov ch, 0
kopiraj:
mov al, [si+2]
mov [si], al
inc si
loop kopiraj
mov [si], '$'
pop si
pop dx
pop cx
pop bx
pop ax
ret 4
readString endp
; Konvertuje string u broj
strtoint proc
push ax
push bx
push cx
push dx
push si
mov bp, sp
mov bx, [bp+14]
mov ax, 0
mov cx, 0
mov si, 10
petlja1:
mov cl, [bx]
cmp cl, '$'
je kraj1
mul si
sub cx, 48
add ax, cx
inc bx
jmp petlja1
kraj1:
mov bx, [bp+12]
mov [bx], ax
pop si
pop dx
pop cx
pop bx
pop ax
ret 4
strtoint endp
; Konvertuje broj u string
inttostr proc
push ax
push bx
push cx
push dx
push si
mov bp, sp
mov ax, [bp+14]
mov dl, '$'
push dx
mov si, 10
petlja2:
mov dx, 0
div si
add dx, 48
push dx
cmp ax, 0
jne petlja2
mov bx, [bp+12]
petlja2a:
pop dx
mov [bx], dl
inc bx
cmp dl, '$'
jne petlja2a
pop si
pop dx
pop cx
pop bx
pop ax
ret 4
inttostr endp
start:
; postavljanje segmentnih registara
ASSUME cs: code, ss:stek
mov ax, data
mov ds, ax
; Mesto za kod studenata
writeString poruka1
; Unos broja elemenata
push 3
push offset strN
call readString
; Pretvaranje strN u broj
push offset strN
push offset N
call strtoint
call novired
writeString strN
; Unos elemenata niza
mov cx, N
mov di, 0
mov si, 0
unos:
call novired
writeString poruka2
push 6
push offset strM
call readString
mov al, strM
mov niz1[di], al
add di, 2
add si, 1
loop unos
call novired
mov cx, N
mov di, 0
mov si, 0
ispis:
writeString niz1[di]
add di, 2
add si, 1
loop ispis
krajPrograma
ends
end start
I input an array of string and then the program prints them. But the program prints only the 1st characters of input strings ...
What else could the program print if the 1st character is all that you store in memory?
mov al, strM
mov niz1[di], al
add di, 2
... and jumbled text.
With add di, 2 you leave an undetermined byte between any two of these 1st characters. That's not going to look nice. Make that byte the DOS string terminator $.
Your writeString macro does not load an address but a word from memory. That's not going to work. The invokation writeString niz1[di] gets expanded into mov dx, offset niz1[di]. What you need here is LEA instead of MOV.
Try the following:
....
unos:
call novired
writeString poruka2
push 6
push offset strM
call readString
mov al, strM
MOV AH, "$"
mov niz1[di], AX
add di, 2
loop unos
call novired
mov cx, N
mov di, 0
ispis:
LEA DX, niz1[di]
MOV AH, 09h
INT 21h
add di, 2
loop ispis
...

What is the flowchart corresponding to the "add-sub" program emu8086?

name "add-sub"
org 100h
mov al, 5 ; bin=00000101b
mov bl, 10 ; hex=0ah or bin=00001010b
add bl, al
sub bl, 1
mov cx, 8
print: mov ah, 2 ; print function.
mov dl, '0'
test bl, 10000000b ; test first bit.
jz zero
mov dl, '1'
zero: int 21h
shl bl, 1
loop print
mov dl, 'b'
int 21h
mov ah, 0
int 16h
ret

Assembler MASM, printing in JNZ loop when value is 0 or below

I'v got a a task to write a program which would create below as output:
ABCD******
ABCD***
ABCD
My code is:
kod segment
org 100h
assume cs:kod
start:
mov cx,3
mov bx,3
mov ax,6
mov ah, 02h
PETLA_ZEW:
push cx
mov cx,4
mov dl, 'A'
PETLA_CIAG:
int 21h
inc dl
dec cx
jnz PETLA_CIAG
push ax
mov cx, ax
mov dl, '*'
PETLA_GWIAZD:
int 21h
dec cx
jnz PETLA_GWIAZD
sub ax, 3
mov dl, 0ah
int 21h
mov dl, 0dh
int 21h
push bx
mov cx, bx
mov dl, ' '
PETLA_SPACJE:
int 21h
dec bx
jnz PETLA_SPACJE
pop bx
add bx, 3
pop cx
dec cx
jnz PETLA_ZEW
koniec:
mov ah, 4ch
int 21h
kod ends
end start
but the problem is that in loop called PETLA_GWIAZD when I subtract ax 2nd time it's value is 0, which is causing the infinite loop. Is there any other loop I should use when subtracting? Maybe some validation check just before the loop? I just started working with Assembly and still do not know a lot...
Thanks!
The problem is the registers you are using : AX and CX are used for interrupts and loops, so you can use other registers, for example, SI instead of CX and DI instead of AX :
kod segment
org 100h
assume cs:kod
start:
mov si,3 ;◄■■ INSTEAD OF CX.
mov bx,3
mov di,6 ;◄■■ INSTEAD OF AX.
mov ah, 02h
PETLA_ZEW:
mov cx,4
mov dl, 'A'
PETLA_CIAG:
int 21h
inc dl
dec cx
jnz PETLA_CIAG
cmp di, 0 ;◄■■ IF COUNTER == 0 ...
je koniec ;◄■■ ... NO MORE ASTERISKS.
mov cx, di ;◄■■
mov dl, '*'
PETLA_GWIAZD:
int 21h
dec cx
jnz PETLA_GWIAZD
sub di, 3 ;◄■■
mov dl, 0ah
int 21h
mov dl, 0dh
int 21h
push bx
mov cx, bx
mov dl, '_'
PETLA_SPACJE:
int 21h
dec bx
jnz PETLA_SPACJE
pop bx
add bx, 3
dec si ;◄■■
jnz PETLA_ZEW
koniec:
mov ah, 4ch
int 21h
kod ends
end start

Loop and decrease counter not working - assembly

I am new to assembly language and was asked to have a program that will allow only three chances of error when typing the password in.
s:
main proc
mov ax, #data
mov ds, ax
mov cx, 3
again:
mov ah, 9
lea dx, a
int 21h
mov ah, 2
mov dl, '*'
int 21h
mov ah, 8
int 21h
mov bl, al
mov ah, 2
cmp bl, 'Y'
je second
cmp bl, 'y'
je second
jne iinvalid
second:
mov ah, 2
mov dl, '*'
int 21h
mov ah, 8
int 21h
mov bh, al
mov ah, 2
cmp bh, 'E'
je third
cmp bh, 'e'
je third
jne iinvalid
third:
mov ah, 2
mov dl, '*'
int 21h
mov ah, 8
int 21h
mov cl, al
mov ah, 2
cmp cl, 'S'
je welcome
cmp cl, 's'
je welcome
jne iinvalid
iinvalid:
jmp invalid
checking:
mov ah, 9
lea dx, i
int 21h
jmp exit
togo:
loop again
welcome:
mov ah,9
lea dx, c
int 21h
lea dx, d
int 21h
mov ah, 1
int 21h
mov bl, al
newp:
mov ah, 9
lea dx, i
int 21h
jmp exit
invalid:
mov ah, 9
lea dx, b
int 21h
mov ah, 1
int 21h
mov cl, al
cmp cl, 'Y'
je togo
cmp cl, 'y'
je togo
jne exit
exit:
mov ah, 4ch
int 21h
main endp
end s
you destroy the content of cx inside the loop.
easiest way to fix it:
mov cx, 3
again:
push cx ; save loop cnt on stack
mov ah, 9
...
togo:
pop cx ; restore cnt from stack
loop again
keep in mind, that if you jump out of the loop, cx must still be removed from stack
welcome:
pop cx ; purge cnt from stack
mov ah,9
just a hint:
you compare the characters entered, to be either lowercase, or uppercase
uppercase and lowercase characters are (in ascii) identically, except of bit 0x20. you could "mask out" this bit by an AND with 0xDF ( 1101 1111 binary), and check the characters with just a single branch (instead of 3):
cmp bl, 'Y'
je second
cmp bl, 'y'
je second
jne iinvalid
--->
and bl, 0xdf ; make lowercase to uppercase
cmp bl, 'Y' ; THEN here both 'y' and 'Y' match
jne iinvalid

How to print an array in DOS x86 assembly?

I have this code to copy the array "NUMBERS" to "DEST" such that no number will repeat (in this case it should be : 1,2,5,4,7)
The code works but now I need to print the array "DEST". How can I do that ?
data segment
NUMBERS db 1,2,1,1,1,5,5,4,7,7
DEST dt ?
data ends
code segment
assume ds:data, cs:code
start: mov ax, data
mov ds, ax
mov ax, 0a0ah
mov di, offset NUMBERS
mov bx, 0h
loop2:mov cl, [di]
mov si, offset DEST
mov ch, [si]
loop1:cmp ch, cl
je dontadd
inc si
mov ch, [si]
dec ah
jnz loop1
mov si, offset DEST
add si, bx
inc bx
mov [si], cl
dontadd:mov ah, 0ah
inc di
dec al
jnz loop2
mov ah, 4ch
int 21h
code ends
end start
You can use INT 21h, AH=02h to print a single character to STDOUT.
MOV CX,10
MOV SI,OFFSET DEST
print:
MOV DL,[si]
OR DL,DL
JE done
ADD DL,'0' ; <-- Convert numeric value in DL into ASCII code
MOV AH,02h
INT 21h
MOV DL,' ' ; Throw in a space to make things pretty
INT 21h
INC SI
LOOP print
done:
If elements in NUMBERS have values over 9 then you need more elaborate conversion of the numeric values into ASCII.
First convert numbers to string then print them.You can use this two macros for printing numbers:
printstr macro str
push ax
push dx
lea dx,str
mov ah,9
int 21h
pop dx
pop cx
endm
printnum macro n
local o,w,s,n5,lb1,lb2,lb3
pusha
push si
push di
jmp w
s db 7 dup('$')
w:
mov si,0
mov cx,7
o:mov s[si],'$'
inc si
loop o
mov si,0
xor ax,ax
mov ax,n
xor dx,dx
cmp ax,0
jge n5
mov bl,'-'
mov s[si],bl
inc si
neg ax
n5:mov cx,10
div cx
or dl,30h
mov s[si],dl
xor dx,dx
inc si
cmp ax,0
jne n5
mov si,0
cmp s[si],'-'
jne lb1
inc si
lb1:mov di,si
lb3:cmp s[si],'$'
je lb2
mov al,s[si]
push ax
inc si
jmp lb3
lb2:pop ax
mov s[di],al
inc di
cmp di,si
jl lb2
printstr s
pop di
pop si
popa
endm

Resources