Ive never really used structs so here it goes... I created the id3 header structure
ID3_HEADER STRUCT
tid byte 3
title byte 30
artist byte 30
album byte 30
year byte 4
comment byte 30
genre byte 1
ID3_HEADER ENDS
then in .data I have
id3 ID3_HEADER <>
but when i try to reference it in my code "id3.title" or so on i get a "syntax error title"... Ive googled Ive searched I cant seem to get past this I know its something so easy.. Any input on what it could be?
"title" is a reserve word in MASM. Change it to "title1" or similar.
assembled perfectly now thank you! I feel like a retard now :red
I would not worry, we have all done it. :bg
Hi
; ########################################
.386
.model flat, stdcall
option casemap :none
; ########################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
; ########################################
ID3Tag STRUCT
szTitle db 31 dup (?)
szArtist db 31 dup (?)
szAlbum db 31 dup (?)
szYear db 5 dup (?)
szComment db 29 dup (?)
ID3Tag ENDS
; ########################################
.data
szTestMp3 db "test1.mp3", 0
; ########################################
.data?
szID3Tag db 122 dup (?)
hFile dd ?
nTmp dd ?
id3 ID3Tag <>
; ########################################
.code
start:
invoke CreateFile, addr szTestMp3, GENERIC_READ, \
FILE_SHARE_READ, 0, \
OPEN_EXISTING, 0, 0
mov hFile, eax
invoke SetFilePointer, eax, -125, 0, FILE_END
invoke ReadFile, hFile, addr szID3Tag, 122, addr nTmp, 0
invoke CloseHandle, hFile
lea edi, szID3Tag
lea esi, id3.szTitle
xor ecx, ecx
@@:
mov al, byte ptr [edi]
mov byte ptr [esi], al
inc edi
inc esi
inc ecx
cmp ecx, 30
jne @B
lea esi, id3.szArtist
xor ecx, ecx
@@:
mov al, byte ptr [edi]
mov byte ptr [esi], al
inc edi
inc esi
inc ecx
cmp ecx, 30
jne @B
lea esi, id3.szAlbum
xor ecx, ecx
@@:
mov al, byte ptr [edi]
mov byte ptr [esi], al
inc edi
inc esi
inc ecx
cmp ecx, 30
jne @B
lea esi, id3.szYear
xor ecx, ecx
@@:
mov al, byte ptr [edi]
mov byte ptr [esi], al
inc edi
inc esi
inc ecx
cmp ecx, 4
jne @B
lea esi, id3.szComment
xor ecx, ecx
@@:
mov al, byte ptr [edi]
mov byte ptr [esi], al
inc edi
inc esi
inc ecx
cmp ecx, 28
jne @B
invoke MessageBox, 0, addr id3.szTitle, 0, 0
invoke MessageBox, 0, addr id3.szArtist, 0, 0
invoke MessageBox, 0, addr id3.szAlbum, 0, 0
invoke MessageBox, 0, addr id3.szYear, 0, 0
invoke MessageBox, 0, addr id3.szComment, 0, 0
invoke ExitProcess, 0
end start
; ########################################
Do you mind explaining why you did it this way:
lea edi, szID3Tag
lea esi, id3.szTitle
xor ecx, ecx
@@:
mov al, byte ptr [edi]
mov byte ptr [esi], al
inc edi
inc esi
inc ecx
cmp ecx, 30
jne @B
and why you couldnt do something as simple as just printing the id3.title or whatever?
Travis,
Look at the structure, it is a set of string addresses so there is no "simple" way to display it, you must write string data to each address and read the data as string data from that address.
So in his example he is pretty much starting at the beginning of the data and counting each byte up till he gets to 30,29 or whatever the tag size is in the struct then prints it out? I think I get it now thanks :)
No, the structure will do that for you, what you need to control with a structure like this is reading and writing to and from the structure. What you must also ensure is that the string data you write to it does not exceed the field length which is set in the byte count of eacyh structure member.
AH! Thank you, I now understand structures alot more and using pointer registers better! :bg
Travis,
Note that the wordd "comment" is a masm reserve word as well. Tell us what you are trying to do with the structure and we may have a suggestion to help you out.
LATER : I deleted the example because it had an error in it.
Well the reason I used a structure was because in C I was able to create a structure and then just:
memcpy(&id3header,ID3,128);
ID3 was my buffer of 128 bytes of data and &id3header was a pointer to my structure so it was able to I guess you could say fill it in, So i came to realize that I wasn't able to do it the same way in assembly. Which is ok I learned more :) but the method that ragdog worked out fine. I commented what he did maybe you could see if im understanding it right?
lea edi,mp3Data ;put offset of mp3data in edi
lea esi,id3.id3tid ;offset of our first field in esi
xor ecx,ecx ;clear ecx (0) so we can count
@@:
mov al, byte ptr [edi] ;put the first/next value and size byte in al
mov byte ptr [esi],al ;now put it into our first field in esi
inc edi ;increment to the next byte
inc esi
inc ecx
cmp ecx, 3 ;till it gets to 3 "TAG"
jne @B
push ecx ;test if its a mp3 file
push offset id3.id3tid ;id3.id3tid should = "TAG"
push offset szTAG
call szCmpi
Thanks everyone for all your help! Sorry for posting so much I just want to make sure I understand everything correctly :)
Travis,
This is a more generic structure example for string data.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
comment * -----------------------------------------------------
Build this template with
"CONSOLE ASSEMBLE AND LINK"
----------------------------------------------------- *
mystruct STRUCT
item1 db 8 dup (?)
item2 db 12 dup (?)
item3 db 16 dup (?)
item4 db 32 dup (?)
mystruct ENDS
.data
mst mystruct <>
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
fn szCopy,"16",ADDR mst.item1
fn szCopy,"Long Name",ADDR mst.item2
fn szCopy,"Title Text",ADDR mst.item3
fn szCopy,"More Text",ADDR mst.item4
print ADDR mst.item1,13,10
print ADDR mst.item2,13,10
print ADDR mst.item3,13,10
print ADDR mst.item4,13,10
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start