Hi,
I have got a code from Internet. Using that concept I am trying to create a macro in masm but I am getting a syntax error. Can somebody plz guide me with this?
.MODEL TINY
install macro intNum
push ax
mov ax, 0
mov word[intNum*4],Newisr_add
mov word[intNum*4+2],cs
pop ax
endm
.CODE
;----------------------------------------------------------------------------------
LoadOfs EQU 0 ;must match the value in the bootloader source file
INT1C EQU 01CH
;----------------------------------------------------------------------------------
;---------------------- initialize ES segment register
ORG 0
Start: push cs
pop ds
;-----------clear screen
mov ax, 3
int 10h
;---------------------- writing a message on screen at startup, character by character- we can't use int 21h
overdata:
xor di, di
mov ax, 0B800h
mov es, ax
mov si, offset msg0+LoadOfs
mov ah, 41h; attribute byte
cld;
msgloop:
lodsb; loads al with a byte of data pted by ds:si
or al, al
jz Timer
stosw; transfers the contents of al to mem location ptd by es:di
jmp msgloop
;---------------------- done - halt
Timer:install INT1C
xor di, di
mov ax, 0B800h
mov es, ax
mov si, offset msgA+LoadOfs
mov ah, 41h; attribute byte
cld;
msgAloop:
lodsb; loads al with a byte of data pted by ds:si
or al, al
jz Halt0
stosw; transfers the contents of al to mem location ptd by es:di
jmp msgAloop
Halt0: hlt
jmp Halt0
;---------------------- data area in code segment
Msg0 db "We be bootin234!",0
msgA db 'Total minutes elapsed since Kernel start is', 0AH, 0DH
clkcounter db 0
secs db 0
mins db 0
Newisr_add:
cli
inc byte ptr [cs:clkcounter]
cmp byte ptr [cs:clkcounter],18; if clkcounter is 18, it means 1 sec
jz handle_secs
sti
iret
handle_secs:
mov byte ptr[cs:clkcounter],0
inc byte ptr[cs:secs]
cmp byte ptr[cs:secs],60;if secs is 60, it means 1 min
jz handle_mins
sti
iret
handle_mins:
mov byte ptr[cs:secs],0
inc byte ptr[cs:mins]; we are done, now print the number of minutes elapsed
sti
iret
;----------------------------------------------------------------------------------
END Start
I am getting following errors:
D:\masm prog\OS6_Timer>ml /c sect7.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: sect7.asm
sect7.asm(63) : error A2001: immediate operand not allowed
install(4): Macro Called From
sect7.asm(63): Main Line Code
sect7.asm(63) : error A2001: immediate operand not allowed
install(3): Macro Called From
sect7.asm(63): Main Line Code
D:\masm prog\OS6_Timer>
Zulfi.
QuoteI have got a code from Internet.
You got ripped off.
Quote from: zak100 on December 31, 2009, 06:44:36 AM
I am getting following errors:
D:\masm prog\OS6_Timer>ml /c sect7.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: sect7.asm
sect7.asm(63) : error A2001: immediate operand not allowed
install(4): Macro Called From
sect7.asm(63): Main Line Code
sect7.asm(63) : error A2001: immediate operand not allowed
install(3): Macro Called From
sect7.asm(63): Main Line Code
Your macro code isn't Masm syntax.
install macro intNum
push ax
mov ax, 0
mov word ptr ds:[intNum*4],Newisr_add
mov word ptr ds:[intNum*4+2],cs
pop ax
endm
Sorry. I cant figure out this error. I did it in the same way as I did in:
http://www.masm32.com/board/index.php?topic=12036.0
Zulfi.
you really did get ripped off - lol
that macro seems to be missing a couple lines
install macro intNum,Newisr_add
push ax
mov ax, 0
push ds
mov ds,ax
cli ;disable interrupts for the change
mov word ptr ds:[intNum*4],Newisr_add
mov word ptr ds:[intNum*4+2],cs ;word ptr may not be needed here
sti
pop ds
pop ax
endm
then, to use it...
Timer: install 1Ch, INT1C
then rename the interrupt handler to "INT1C" instead of "Newisr_add"
INT1C:
cli ;not needed at the beginning of an interrupt handler - the interrupt clears that flag automatically
Hi,
Delete.
Regards,
Steve N.
Edit:
No, sorry, it should work.
in truth, i think i would be inclined to make it a proc instead of a macro
but, i think you are just experimenting, so it doesn't matter
sometimes, you may want to set several vectors at once
if that is the case, it is more efficient to set DS = 0, CLI, and set them in literal code
Hi,
I am going to try it. Thanks for your attention. I want to ask one question if you dont mind. Why am I getting an error if I dont pass an argument?
Zulfi.
Hi,
I have tried it. I am getting a redefinition error, might be because we are using it as a argument once and 2nd time as a label.
Coreect me if I am wrong.
The new code is given below:
.MODEL TINY
install macro intNum,Newisr_add
local INT1C
push ax
mov ax, 0
push ds
mov ds,ax
cli ;disable interrupts for the change
mov word ptr ds:[intNum*4],Newisr_add
mov word ptr ds:[intNum*4+2],cs ;word ptr may not be needed here
sti
pop ds
pop ax
endm
.CODE
;----------------------------------------------------------------------------------
LoadOfs EQU 0 ;must match the value in the bootloader source file
INT1C EQU 01CH
;----------------------------------------------------------------------------------
;---------------------- initialize ES segment register
ORG 0
Start: push cs
pop ds
;-----------clear screen
mov ax, 3
int 10h
;---------------------- writing a message on screen at startup, character by character- we can't use int 21h
overdata:
xor di, di
mov ax, 0B800h
mov es, ax
mov si, offset msg0+LoadOfs
mov ah, 41h; attribute byte
cld;
msgloop:
lodsb; loads al with a byte of data pted by ds:si
or al, al
jz Timer
stosw; transfers the contents of al to mem location ptd by es:di
jmp msgloop
;---------------------- done - halt
Timer:install 1Ch, INT1C
xor di, di
mov ax, 0B800h
mov es, ax
mov si, offset msgA+LoadOfs
mov ah, 41h; attribute byte
cld;
msgAloop:
lodsb; loads al with a byte of data pted by ds:si
or al, al
jz Halt0
stosw; transfers the contents of al to mem location ptd by es:di
jmp msgAloop
Halt0: hlt
jmp Halt0
;---------------------- data area in code segment
Msg0 db "We be bootin234!",0
msgA db 'Total minutes elapsed since Kernel start is', 0AH, 0DH
clkcounter db 0
secs db 0
mins db 0
INT1C:
cli ;not needed at the beginning of an interrupt handler - the interrupt clears that flag automatically
inc byte ptr [cs:clkcounter]
cmp byte ptr [cs:clkcounter],18; if clkcounter is 18, it means 1 sec
jz handle_secs
sti
iret
handle_secs:
mov byte ptr[cs:clkcounter],0
inc byte ptr[cs:secs]
cmp byte ptr[cs:secs],60;if secs is 60, it means 1 min
jz handle_mins
sti
iret
handle_mins:
mov byte ptr[cs:secs],0
inc byte ptr[cs:mins]; we are done, now print the number of minutes elapsed
sti
iret
;----------------------------------------------------------------------------------
END Start
The error is given below:
D:\masm prog\OS6_Timer>ml /c sect7_2.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: sect7_2.asm
sect7_2.asm(97) : error A2005: symbol redefinition : INT1C
D:\masm prog\OS6_Timer>n below:
my mistake, Zulfi
i did not see that you had used INT1C as an EQUate label
remove this line from the macro
local INT1C
then, we will simply give the handler a unique name
change the macro call:
Timer: install 1Ch, INT1Ch
change the handler name:
INT1Ch:
cli
Hi,
I tried the code with your changes and its working now. I have to print the values of secs, mins and hrs. I am thinking to use daa and das alg which we have done in case of printing register values.
Zulfi.
the AAM instruction may be useful