Hi :bg
doing a little ASM project for school.
problem is, school forces forces us to use some "safe" compiler, that doewnt like long lines, long programs, jumps or students.
obviously, my project (a little game of blackjack) didnt compile, so i decided to test it with another compiler.
it still doesny compile, but of the right reasons this time.
so i decided to post my little project here, for some tips, ideas and such :bg
Thanks on behalf,
Scept.
So... here it is: (comments will later be replaced with actual writing, for now, im ok with them).
.model small
.stack 100h
.data
m db 3h
b db ?
r1 db ?
r2 db ?
r3 db 0
ra db ?
rb db ?
rc db 0
cmptrs db 0
plrs db 0
.code
mov ax,0b800h
mov ds, ax
; begining of program
mov bl,1
mov ah,2
;"welcome"
;"you have"
mov dl,m
add dl,30h
int 21h
;"$"
;"how much would you like to bet on?"
mov ah, 1
int 21h
mov b,al
sub b,30h
call cardpick
mov r1, bh
mov ah,2
;"you got:"
cmp bh, 10
jz royalcard
add bh,30h
mov dl, bh
int 21h
jmp cmptr
royalcard:mov dl,31h
int 21h
mov dl,30h
int 21h
jmp cmptr
cmptr: call cardpick
mov rc, bh
mov ah,2
;"dealer got:"
cmp bh, 10
jz royalcard
add bh,30h
mov dl, bh
int 21h
jmp second
croyacard: call tendis
second: ;"pick another card?"
mov ah, 1
int 21h
cmp al,79h
jnz plrend
call cardpick
mov r3, bh
mov ah,2
;"you got:"
cmp bh, 10
jz royalcard
add bh,30h
mov dl, bh
int 21h
jmp cmptrs
royalcard: call tendis
cmptrs: cmp r1,6
ja card2
call cardpick
mov rc, bh
card1: add plrs,r1
add plrs,r2
add plrs,r3
add cmptrs,ra
add cmptrs,rb
add cmptrs,rc
call cardpick
mov r2, bh
call cardpick
mov rb, bh
; "you got:"
cmp r1, 10
jnz write1
call tendis
jmp card2
write1: add r1,30h
mov dl, r1
int 21h
card2: cmp r2, 10
jnz write2
call tendis
jmp card3
write2: add r2,30h
mov dl, r2
int 21h
card3: cmp r3, 10
jnz write3
call tendis
jmp carda
write3: add r3,30h
mov dl, r3
int 21h
carda: ;"dealer got:"
cmp ra, 10
jnz writea
call tendis
jmp cardb
writea: add ra,30h
mov dl, ra
int 21h
cardb: cmp rb, 10
jnz writeb
call tendis
jmp cardc
writeb: add rb,30h
mov dl, rb
int 21h
cardc: cmp rc, 10
jnz writeb
call tendis
jmp announc
writec: add rc,30h
mov dl, rc
int 21h
announc: cmp plrs,cmptrs
ja pwin
;"you lost..."
sub m,b
pwin: ;"you won!!!"
add m,b
; end of program
mov ah,4ch
int 21h
cardpick: mov bh,{bl}
and bh,00000001b
cmp bh,1
jz royal
mov bh, {bl}
and bh,00000111b
add bh,2
add bl,1
ret
royal: mov r1,10d
add bl,1
ret
tendis: mov ah,2
mov bh,{bl}
and bh,00000011b
cmp bh, 2
jz ten
jb king
cmp bh,3
jz queen
mov dl,4ah
int 21h
ret
queen: mov dl,51h
int 21h
ret
king: mov dl,4bh
int 21h
ret
ten: mov dl,31h
int 21h
mov dl,30h
int 21h
ret
end
We won't do your homework, scept.
If you have problems, then ask more specific questions.
Dont worry, that was not the intention. look in front of you- i did the project. by myself.
i was just looking for some tips to improve efficiency and such, maybe wrong syntax if i have...
besides, where can i find some sort of manual with Defenition of error numbers, so i will be able to understand exactly why it doesnt compile?
Scept,
MASM displays error messages to help you solve the problems.
When I try to assemble your code MASM displays:
Assembling: scept.asm
scept.asm(71) : error A2024: invalid operand size for instruction
scept.asm(72) : error A2005: symbol redefinition : royalcard
scept.asm(73) : error A2005: symbol redefinition : cmptrs
scept.asm(77) : error A2070: invalid instruction operands
scept.asm(78) : error A2070: invalid instruction operands
scept.asm(79) : error A2070: invalid instruction operands
scept.asm(80) : error A2070: invalid instruction operands
scept.asm(81) : error A2070: invalid instruction operands
scept.asm(82) : error A2070: invalid instruction operands
scept.asm(131) : error A2070: invalid instruction operands
scept.asm(134) : error A2070: invalid instruction operands
scept.asm(136) : error A2070: invalid instruction operands
scept.asm(61) : error A2006: undefined symbol : plrend
scept.asm(143) : error A2167: unexpected literal found in expression
scept.asm(147) : error A2167: unexpected literal found in expression
scept.asm(156) : error A2167: unexpected literal found in expression
The first problem is with
jmp cmptrs
You are trying to use a byte variable as a jump destination.
The second and third problems are because you redefined symbols. Both are problems with code labels that are defined more than once in the code. Labels outside of any procedure are visible everywhere. Labels in procedures are visible only within the procedure.
The fourth problem is with
add plrs,r1
And the problem is because plrs and r1 are both memory operands. The add instruction, like most normal instructions, does not support two memory operands. To do this you need to place one of the operands in a register, for example:
mov AL,r1
add plrs,AL
And so on...
Fixing problems like this is relatively easy, because you know where the problem is, and you at least have a hint as to what the problem is.
You can get a reference that list the error messages here:
http://www.masm32.com/board/index.php?topic=3592.0
Thanks alot michael, you helped quite a bit :U
well, i fixed nearly everything, and suddenly got flooded by "error A2074: cannot access label through segment registers".
looked through the manual, i cant quite understand its meaning... and besides, what have i done to make it appear?
and another tiny question-
i wanted to "randomize" a number, so i basicly took a value from a memory cell, whose number is stored in bl, and stored it in bh, like this:
mov bh,{bl}.
in response, MASM said "error A2167: unexpected literal found in expression".
to my understanding, i should use different syntax- but what syntax exactly?
thanks on behalf,
Scept.
Use square brackets [] instead of {}.
When posting errors, can you please post the line number info as well - like MichaelW did:"scept.asm(79) : error A2070: invalid instruction operands" - it really helps... otherwise we all have to download it, assemble it and look at the errors oursleves ("not much hassle at all" you might think, but people can't really be bothered to do it 10 times a day - you will get more answers if we know where to look).
Ossa
Of course i didnt expect you to do it yourself- i just wanted a general answer.
i now tried replacing it with square bracets, and i get this:
(151,155,164) : error A2031: must be index or base register
about error A2074- i meant what i said when i said "i got flooded"-
G:\Eyal\School\JACK.asm(22) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(29) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(30) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(32) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(47) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(63) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(73) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(76) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(77) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(78) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(79) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(80) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(81) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(82) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(83) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(84) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(85) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(86) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(87) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(88) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(90) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(92) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(94) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(98) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(99) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(101) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(105) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(106) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(108) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(112) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(113) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(116) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(120) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(121) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(123) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(127) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(128) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(130) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(134) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(135) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(137) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(138) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(141) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(142) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(144) : error A2074: cannot access label through segment registers
G:\Eyal\School\JACK.asm(145) : error A2074: cannot access label through segment registers
> (151,155,164) : error A2031: must be index or base register
You seem to use 8-bit register as address. You need 16-bit registers instead.
> Error A2074
I think I got a clue why you got those errors.
The small model isn't a flat model. The .data and .code space thus aren't in the same segment, and you need segment registers to access them. There is no segment register pointing to the data segment. Every time you want to access something in the data segment, the compiler complains that there is no segment register pointing the the data segment.
You could place everything in the code segment to solve it.
Thanks Alot :bg
Stab-
changed to 16 bit registers, (cx instead of bh, bx instead of bl)- didnt help.
tried to move everything into data section- with\without deleting "code."- with- lots of random errors, without- "fatal error a1000".
besides, i just checked and i am not allowed to do this- the opening and ending must stay untuched, besides for variables and routines- schools orders.
any ideas?
OK, I really can't remember any DOS programming, BUT i think the following might work:
.model small
OPTION SEGMENT:USE16
.stack 100h
data SEGMENT
m db 3h
b db ?
r1 db ?
r2 db ?
r3 db 0
ra db ?
rb db ?
rc db 0
cmptrs db 0
plrs db 0
data ENDS
code SEGMENT
ASSUME cs:code,ds:data,ss:stack,es:data
org 100h
...
code ENDS
end
This should get rid of some of the errors... there are however, a fair few other errors in your code, most notably that you can't use a pair of memory locations in a single operation (like you did in the line "add m,b") you must use a register as an intermediate.
Make sure that you read what MichaelW has said, he explains nearly all of the mistakes.
Ossa
simply using ASSUME DS:DATA at the beginning of your code will work too.
[edit] must be ASSUME DS:_DATA - checked it[/edit]
[edit] and use [0+bx] for those three lines [/edit]
Thought I'd just say that Stan's method is much better - just ignore what I said.
just in case you can't see where to put the ASSUME though, it goes just after .code:
.code
ASSUME DS:_DATA
Ossa
Thanks- the "ASSUME DS:_DATA "' works perfectly.
ossa- i fixed everything michael stated, of course :P
only one problem left-
the (151,155,164) : error A2031: must be index or base register.
tried changing to 16 bit, didnt do anything.
any ideas?
(a question- why doesnt a statement like "mov r1, bx" work? is it because r1 isnt a 16 bit variable? if so, how do i make him one?)
thanks alot to all of you.
[EDIT]
using [0+cx] made no difference
Scept,
The Microsoft MASM manuals are available here:
http://webster.cs.ucr.edu/Page_TechDocs/index.html
For your most recent questions, see MASM Programmer's Guide, Indirect Memory Operands in Chapter 3, and Declaring Integer Variables in Chapter 4.
For information on the interrupts see Ralf Brown's Interrupt list. An HTML version is here:
http://www.ctyme.com/rbrown.htm
And the download version here:
http://www-2.cs.cmu.edu/~ralf/files.html
Thanks, ill look into that.
(by the way, the interupts part wouldnt be very usefull, since we are only allowed to use int 21h :P)
[EDIT]
tried the syntax in chapter three, stil same problem... (error A2031) in here:
mov bx,[cx]
anyone? im starting to get a bit desperate...
:(
Well, fixed that problem by changing the operand into a variable, but....
"assemble & link" doesnt work.
Gives me "fatal error LNK1190: invalid fixup found, type 0X0001".
what does it mean, and what can i do about it?
thanks on behalf.