Hello all,
I'm a newbie. I linked the files IOP.obj and Example1.obj by using following command:
> link IOP.obj + Example1.obj
Everything was fine but a warning appeared "LINK : warning L4038: program has no starting address." I searched alot on google but couldn't find any idea. Please check the coding of both the files IOP.asm and Example1.asm and give me any clue.
__________________________
IOP.asm
__________________________
CR EQU 0DH ;CARRIAGE RETURN CONSTANT
LF EQU 0AH ;LINE FEED CONSTANT
PUBLIC GETCHAR, PUTCHAR, NEWLINE, MESSAGE, OUTDEC, INDEC
IOPCODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:IOPCODE
GETCHAR PROC FAR
;INPUTS A SINGLE CHARACTER WITH ASCII CODE/VALUE INTO AL
MOV AH,1 ;O/S FUNCTION 1
INT 21H
RET
GETCHAR ENDP
PUTCHAR PROC FAR
;DISPLAYS A SINGLE CHARACTER WITH ASCII CODE/VALUE INTO PLACE IN DL
MOV AH,2 ;O/S FUNCTION 2
INT 21H
RET
PUTCHAR ENDP
NEWLINE PROC FAR
;INSERTS A NEWLINE FROM THE CURSOR POSITION
MOV DL, CR
CALL PUTCHAR
MOV DL, LF
CALL PUTCHAR
RET
NEWLINE ENDP
MESSAGE PROC FAR
;DISPLAYS A $ TERMINATED STRING/MESSAGE WHOSE EFFECTIVE ADDRESS IS PLACED IN DS:DX
MOV AH,9 ;O/S FUNCTION 1
INT 21H
RET
MESSAGE ENDP
INDEC PROC FAR
; INPUTS AN UNSINGNED INTEGER VALUE FROM THE KEYBOARD AND PLACES IT ONTO AX : REGISTER
; THE NUMBER IS ENTERED AS 1 OR MORE DECIMAL DIGITS AND TERMINATED BY ENTERING A CHARACTER OTHER THAN 0-9.
; MAKE SURE TO ENTER A VALID VALUE I.E 0-65535.
PUSH BX ;SAVE REGISTERS TO BE CHANGED
PUSH CX
PUSH DX
MOV CX,10 ; MULTIPLYER IS KEPT IN CX
MOV BX,0 ; INITIALIZE THE INTERMEDIATE RESULT
AGAIN: CALL GETCHAR; READ A CHARACTER FROM KEYBOARD
CMP AL,'0' ; COMPARE WETHER AL<'0'
JB EXIT ; IF AL<'0' THEN EXIT
CMP AL,'9' ; COMPARE WETHER AL> '0'
JA EXIT
;NOW THE CHARACTER IS A VALID INTEGER CHARACTER
SUB AL,'0'; CONVETS THE CHARACTER INTEGER INTO INTEGER
PUSH AX ;SAVE THE DIGIT I.E AL
MOV AX,BX ;PLACE THE MULTIPLICANT INTO AX
MUL CX ;MULIPLIER IS A WORD. EFFECT WILL BE DX:AX <-- AX*CX
MOV BX,AX ; IN CASE, DX WILL BE ZERO, MULTIPLIED INTERMEDIATE RESULT
POP AX ;RESULT THE DIGIT
XOR AH,AH ; MAKE AH = 0, TO KEEP DIGIT IN AX
JMP AGAIN ; LOOP BACK TO REPEAT THE STATEMENTS FROM AGAIN MARK
EXIT: MOV AX,BX ; PLACE THE DEVISOR IN AX
POP DX
POP CX
POP BX
RET
INDEC ENDP
OUTDEC PROC FAR
;DISPLAYS AN UNSIGNED DECIMAL NUMBER PLACE IN AX REGISTER.
PUSH AX ;SAVE THE REGISTERS
PUSH BX
PUSH CX
PUSH DX
MOV CX,0 ; INITIALIZE THE DIGIT COUNTER
MOV BX,10 ; INITIALIZE THE DIVISOR
MOV DX,0 ;TO BE USED IN DIVISION AND TO AVOID GARBAGE
AGAIN : DIV BX ; QUOTIENT (AX) = (DX:AX)/BX AND REMAINDER DX =(DX:AX)/BX
PUSH DX ; SAVE/KEEP THE REMAINDER(I.E DIGIT)
INC CL ; CL = CL+1, INCREMENTS THE COUNTER BY 1
CMP AX,0 ; CHECK WETHER THE QUOTIENT IS ZERO
JA AGAIN ; IF ZERO REPEAT THE DIVISION
NEXT : POP DX ; REMOVE THE DIGIT FROM STACK
ADD DL, 30H ; MAKE/CONVERT THE DIGIT INTO ASCII/CHAR DIGIT
CALL PUTCHAR ; DISPLAYS DL
LOOP NEXT ; REPEAT THE STEPS UNTILL THE DIGIT COUNTER IS ZERO
POP DX
POP CX
POP BX
POP AX
RET
OUTDEC ENDP
IOPCODE ENDS
END
__________________________
Example1.asm
__________________________
EXTRN INDEC : FAR, OUTDEC: FAR, NEWLINE : FAR, MESSAGE : FAR
MYDATA SEGMENT PARA 'DATA'
N1 DW ? ; DEFINE/DECLARE A VARIABLE N1
N2 DW ? ; DEFINE/DECLARE A VARIABLE N2
SUM DW ?
M1 DB "ENTER 1ST NO. = $"
M2 DB "ENTER 2ND NO. = $"
M3 DB "SUM OF THE NUMBERS = $"
MYDATA ENDS
MYSTACK SEGMENT PARA STACK 'STACK'
DB 128 DUP (?)
MYSTACK ENDS
MYCODE SEGMENT PARA 'CODE'
ASSUME SS:MYSTACK, CS:MYCODE, DS:MYDATA
MOV AX,MYDATA ;INITIALIZE THE DS TO DATA SEGMENT
MOV DS,AX
LEA DX,M1 ; MOVE OFFSET IN DX
CALL MESSAGE
CALL INDEC ; INPUT 1ST DECIMAL NUMBER INTO AX
MOV N1,AX ; STORE THE 1ST NUMBER
LEA DX,M2 ;
CALL MESSAGE ;
CALL INDEC ; INPUT 2ND DECIMAL NUMBER INTO AX
MOV N2,AX ;
MOV AX,N1 ; AX = N1
ADD AX,N2 ; AX = AX(N1) + N2
MOV SUM,AX ; SUM = AX
LEA DX,M3 ; 3RD MESSAGE
CALL MESSAGE
MOV AX,SUM
CALL OUTDEC
MOV AH,4CH
INT 21H
MYCODE ENDS
END
___________________________
I'm a newbie. I linked the files IOP.obj and Example1.obj by using following command:
> link IOP.obj + Example1.obj
Everything was fine but a warning appeared "LINK : warning L4038: program has no starting address." I searched alot on google but couldn't find any idea. Please check the coding of both the files IOP.asm and Example1.asm and give me any clue.
__________________________
IOP.asm
__________________________
CR EQU 0DH ;CARRIAGE RETURN CONSTANT
LF EQU 0AH ;LINE FEED CONSTANT
PUBLIC GETCHAR, PUTCHAR, NEWLINE, MESSAGE, OUTDEC, INDEC
IOPCODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:IOPCODE
GETCHAR PROC FAR
;INPUTS A SINGLE CHARACTER WITH ASCII CODE/VALUE INTO AL
MOV AH,1 ;O/S FUNCTION 1
INT 21H
RET
GETCHAR ENDP
PUTCHAR PROC FAR
;DISPLAYS A SINGLE CHARACTER WITH ASCII CODE/VALUE INTO PLACE IN DL
MOV AH,2 ;O/S FUNCTION 2
INT 21H
RET
PUTCHAR ENDP
NEWLINE PROC FAR
;INSERTS A NEWLINE FROM THE CURSOR POSITION
MOV DL, CR
CALL PUTCHAR
MOV DL, LF
CALL PUTCHAR
RET
NEWLINE ENDP
MESSAGE PROC FAR
;DISPLAYS A $ TERMINATED STRING/MESSAGE WHOSE EFFECTIVE ADDRESS IS PLACED IN DS:DX
MOV AH,9 ;O/S FUNCTION 1
INT 21H
RET
MESSAGE ENDP
INDEC PROC FAR
; INPUTS AN UNSINGNED INTEGER VALUE FROM THE KEYBOARD AND PLACES IT ONTO AX : REGISTER
; THE NUMBER IS ENTERED AS 1 OR MORE DECIMAL DIGITS AND TERMINATED BY ENTERING A CHARACTER OTHER THAN 0-9.
; MAKE SURE TO ENTER A VALID VALUE I.E 0-65535.
PUSH BX ;SAVE REGISTERS TO BE CHANGED
PUSH CX
PUSH DX
MOV CX,10 ; MULTIPLYER IS KEPT IN CX
MOV BX,0 ; INITIALIZE THE INTERMEDIATE RESULT
AGAIN: CALL GETCHAR; READ A CHARACTER FROM KEYBOARD
CMP AL,'0' ; COMPARE WETHER AL<'0'
JB EXIT ; IF AL<'0' THEN EXIT
CMP AL,'9' ; COMPARE WETHER AL> '0'
JA EXIT
;NOW THE CHARACTER IS A VALID INTEGER CHARACTER
SUB AL,'0'; CONVETS THE CHARACTER INTEGER INTO INTEGER
PUSH AX ;SAVE THE DIGIT I.E AL
MOV AX,BX ;PLACE THE MULTIPLICANT INTO AX
MUL CX ;MULIPLIER IS A WORD. EFFECT WILL BE DX:AX <-- AX*CX
MOV BX,AX ; IN CASE, DX WILL BE ZERO, MULTIPLIED INTERMEDIATE RESULT
POP AX ;RESULT THE DIGIT
XOR AH,AH ; MAKE AH = 0, TO KEEP DIGIT IN AX
JMP AGAIN ; LOOP BACK TO REPEAT THE STATEMENTS FROM AGAIN MARK
EXIT: MOV AX,BX ; PLACE THE DEVISOR IN AX
POP DX
POP CX
POP BX
RET
INDEC ENDP
OUTDEC PROC FAR
;DISPLAYS AN UNSIGNED DECIMAL NUMBER PLACE IN AX REGISTER.
PUSH AX ;SAVE THE REGISTERS
PUSH BX
PUSH CX
PUSH DX
MOV CX,0 ; INITIALIZE THE DIGIT COUNTER
MOV BX,10 ; INITIALIZE THE DIVISOR
MOV DX,0 ;TO BE USED IN DIVISION AND TO AVOID GARBAGE
AGAIN : DIV BX ; QUOTIENT (AX) = (DX:AX)/BX AND REMAINDER DX =(DX:AX)/BX
PUSH DX ; SAVE/KEEP THE REMAINDER(I.E DIGIT)
INC CL ; CL = CL+1, INCREMENTS THE COUNTER BY 1
CMP AX,0 ; CHECK WETHER THE QUOTIENT IS ZERO
JA AGAIN ; IF ZERO REPEAT THE DIVISION
NEXT : POP DX ; REMOVE THE DIGIT FROM STACK
ADD DL, 30H ; MAKE/CONVERT THE DIGIT INTO ASCII/CHAR DIGIT
CALL PUTCHAR ; DISPLAYS DL
LOOP NEXT ; REPEAT THE STEPS UNTILL THE DIGIT COUNTER IS ZERO
POP DX
POP CX
POP BX
POP AX
RET
OUTDEC ENDP
IOPCODE ENDS
END
__________________________
Example1.asm
__________________________
EXTRN INDEC : FAR, OUTDEC: FAR, NEWLINE : FAR, MESSAGE : FAR
MYDATA SEGMENT PARA 'DATA'
N1 DW ? ; DEFINE/DECLARE A VARIABLE N1
N2 DW ? ; DEFINE/DECLARE A VARIABLE N2
SUM DW ?
M1 DB "ENTER 1ST NO. = $"
M2 DB "ENTER 2ND NO. = $"
M3 DB "SUM OF THE NUMBERS = $"
MYDATA ENDS
MYSTACK SEGMENT PARA STACK 'STACK'
DB 128 DUP (?)
MYSTACK ENDS
MYCODE SEGMENT PARA 'CODE'
ASSUME SS:MYSTACK, CS:MYCODE, DS:MYDATA
MOV AX,MYDATA ;INITIALIZE THE DS TO DATA SEGMENT
MOV DS,AX
LEA DX,M1 ; MOVE OFFSET IN DX
CALL MESSAGE
CALL INDEC ; INPUT 1ST DECIMAL NUMBER INTO AX
MOV N1,AX ; STORE THE 1ST NUMBER
LEA DX,M2 ;
CALL MESSAGE ;
CALL INDEC ; INPUT 2ND DECIMAL NUMBER INTO AX
MOV N2,AX ;
MOV AX,N1 ; AX = N1
ADD AX,N2 ; AX = AX(N1) + N2
MOV SUM,AX ; SUM = AX
LEA DX,M3 ; 3RD MESSAGE
CALL MESSAGE
MOV AX,SUM
CALL OUTDEC
MOV AH,4CH
INT 21H
MYCODE ENDS
END
___________________________
You need a start: label to signify where the execution begins.
Thanks a lot.
It really resolved my problem and now I can link my object files without any warning. Thanks again.
bye
It really resolved my problem and now I can link my object files without any warning. Thanks again.
bye