EASy68K  
It is currently Tue Oct 15, 2019 12:08 am

All times are UTC




Post new topic Reply to topic  [ 15 posts ] 
Author Message
PostPosted: Tue Dec 20, 2011 11:33 am 
Offline

Joined: Fri Dec 16, 2011 12:32 am
Posts: 17
Hello everyone. What would be the easiest way to make a program that counts the numbers of letters in a string? Also, I have been looking through some programs and I have noticed that a string is declared as

Code:
string   dc.b  'This is a string',0


First of all isn't this more than one byte? I understand that one byte, for example $F4, takes up 8 bits and is represented by one address. How does it work for strings? How many letters are assigned to one address? Why is there a 0 after?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 20, 2011 12:22 pm 
Offline
User avatar

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1102
When used with a literal string, the dc.b directive places the ASCII code for each character in memory. Looking at the .L68 file created we can see the ASCII codes 54 'T', 65 'e', etc.

00001000= 54 65 78 74 00 10 string dc.b 'Text',0

The ,0 at the end of the string places the binary number 0 in memory at the end of the string. This is called a NULL terminated string. The string display trap tasks in EASy68K are designed to work with NULL terminated strings.

The length of a NULL terminated string may be determined by simply counting the bytes of data until the 0 is reached.

Code:
  clr.l d1          ; size=0
  lea string,a0     ; point to string
  while.b (a0,d1) <ne> #0 do.s  ; while not NULL
    addq.l #1,d1    ; increment size
  endw

_________________
Prof. Kelly


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 03, 2012 9:46 am 
Offline

Joined: Fri Dec 16, 2011 12:32 am
Posts: 17
profkelly wrote:
When used with a literal string, the dc.b directive places the ASCII code for each character in memory. Looking at the .L68 file created we can see the ASCII codes 54 'T', 65 'e', etc.

00001000= 54 65 78 74 00 10 string dc.b 'Text',0

The ,0 at the end of the string places the binary number 0 in memory at the end of the string. This is called a NULL terminated string. The string display trap tasks in EASy68K are designed to work with NULL terminated strings.

The length of a NULL terminated string may be determined by simply counting the bytes of data until the 0 is reached.

Code:
  clr.l d1          ; size=0
  lea string,a0     ; point to string
  while.b (a0,d1) <ne> #0 do.s  ; while not NULL
    addq.l #1,d1    ; increment size
  endw


Thank you for the explanation for how a string is stored in memory. It is clear to me now.

I'm afraid I don't completely understand this code.

Code:
clr.l d1     


Writes 32 zeros into register d1


Code:
lea string,a0       


This is the same as movea and moves the address of the label string to register a0. Shouldn't we use immediate adressing here? Or is it the same thing? Like this:

Code:
movea #string,a0       


continuing...

Code:
 while.b (a0,d1) <ne> #0 do.s     


I'm afraid this line of code is not clear to me. I've never done a while loop before. This syntax is new to me. while.b (a0,d1) is this comparing a0 and d1, that is subtracting one from the other? ne is for not equal? why are there <> . What does this part do: #0 do.s?

Code:
addq.l #1,d1   


This is my first encounter with add quick. It just adds the the value 1 to d1. What is the difference between add.l and addq.l?

Code:
 endw   


What does this do?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 03, 2012 3:22 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
LEA tends to be more efficient and permits the assembler some scope to create address independent code. This is more of an issue when using relocatable tools.

(A0,D1) is looking at the byte at address A0.L+D1.W

The WHILE loop is looking to count through BYTES NOT EQUAL TO ZERO. When it gets to a ZERO byte it has reached the end of the string.

ENDW closes the WHILE loop (END WHILE), the WHILE/DO/ENDW are a high level construct of the assembler

The quick form of the add encodes more efficiently. Some assemblers can figure out if an ADD can be encoded using the quick form, as it uses less words and executes quicker.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 18, 2012 5:55 pm 
Offline

Joined: Fri Dec 16, 2011 12:32 am
Posts: 17
clive wrote:
LEA tends to be more efficient and permits the assembler some scope to create address independent code. This is more of an issue when using relocatable tools.

(A0,D1) is looking at the byte at address A0.L+D1.W

The WHILE loop is looking to count through BYTES NOT EQUAL TO ZERO. When it gets to a ZERO byte it has reached the end of the string.

ENDW closes the WHILE loop (END WHILE), the WHILE/DO/ENDW are a high level construct of the assembler

The quick form of the add encodes more efficiently. Some assemblers can figure out if an ADD can be encoded using the quick form, as it uses less words and executes quicker.


Two additional questions.

1.Must we use a 0 to terminate the string? Or can we choose any ASCII character? For example, G. If not, did the simulator designers decide to use a 0 or the designers of the 68k processor? Or both.

2.What if we have a zero in the string?

Code:
string   dc.b  'This is a 0string',0


Will the string be terminated before the s? If not how does the program know which 0 to look at?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 18, 2012 8:07 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
Zero (NUL) is a classic end-of-string marker, it is used by C, and is easy to test for. Google "Null Terminated Strings"

The ASCII character '0' is 48 decimal, $30 hexadecimal, this is NOT a NUL which is 0 decimal, $00 hexadecimal.

Other representations:

PASCAL strings typically have a length byte ahead of the characters.

Other systems have use '$' as a string termination character.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 18, 2012 9:29 pm 
Offline

Joined: Fri Dec 16, 2011 12:32 am
Posts: 17
clive wrote:
Zero (NUL) is a classic end-of-string marker, it is used by C, and is easy to test for.

The ASCII character '0' is 48 decimal, $30 hexadecimal, this is NOT a NUL which is 0 decimal, $00 hexadecimal.


Thanks for the reply. C uses \0 but this is treated a single character. I just tried modifying a program in the simulator $ff also worked. So, we don't have to use 0 to terminate a string do we. In C we must use \0 correct?

Code:
string   dc.b  'This is a 0string',0


Will not end before the s since every character(including spaces) inside the single quotation marks is treated as an ASCII character. The 0 in front of the s is written into memory as 48. The 0 after the comma is not converted to its eight bit ASCII representation but is rather converted to its hexadecimal value which is 00. Is all this correct?

What is the maximum number of elements a string can contain?

Code:
string   dc.b  'This is a string',0


Using this same code I placed 266 letters in between the quotation marks and got an error. What is the max value of letters I can put. What effect does changing the .b to .w or .l have if any?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 18, 2012 9:52 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
Like with anything programmed, you can choose how you want to implement things. NUL is used because it is a non-printable character. It is convenient because a zero flag will pick it up. The processor really doesn't care.

Easy68K probably has a string printing function that expects ASCIIZ formatted strings. It is a pretty standard way of representing strings over many different chips and OS.

The length is limited by the system/implementation. It is not very efficient to enumerate long strings repetitively. Assuming you are limited by D1.W in this example, the maximum printable characters is 65535. Other examples could be written to deal with 4GB strings, but this is neither effective or practical.

The assembler may have other limits, strings could span over several lines if there is a line limit in the assembler.

The quoted text ('') is stored as ASCII characters, dc.b will normally just store byte(s) as specified.

Code:
  dc.b 1,2,3,4
  dc.b $41,$53,$53,$00
  dc.b 'This '
  dc.b 'is '
  dc.b 'a test', 0


Using DC.W or DC.D doesn't make a lot of sense for ASCII characters, DC.W would be useful for Unicode characters, but you'd then have to step through it two bytes at a time.


Last edited by clive on Thu Jan 19, 2012 1:22 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 19, 2012 1:08 pm 
Offline
User avatar

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1102
assemlbey_dude wrote:
Thanks for the reply. C uses \0 but this is treated a single character. I just tried modifying a program in the simulator $ff also worked. So, we don't have to use 0 to terminate a string do we.


A null terminated string must end with binary 0, $ff does not work as a string terminator.
Code:
   ORG   $1000
START:    ; first instruction of program

    move.b  #14,d0
    lea string,a1
    trap    #15
    MOVE.B   #9,D0
    TRAP #15  ; halt simulator

* Variables and Strings
string dc.b '0123456789',$ff,'$ff did not work',0
  END  START  ; last line of source


assemlbey_dude wrote:
In C we must use \0 correct?

Code:
string   dc.b  'This is a 0string',0


Will not end before the s since every character(including spaces) inside the single quotation marks is treated as an ASCII character. The 0 in front of the s is written into memory as 48. The 0 after the comma is not converted to its eight bit ASCII representation but is rather converted to its hexadecimal value which is 00. Is all this correct?

Yes, your description of the EASy68K string is correct. In C a null terminated string is created by default when literal strings are used.
Code:
char str[] = "Creates null terminated string";

The null characters may be encoded using \0 or literal 0.
Code:
char str2[] = {'A','B','C','\0'};
char str3[] = {'D','E','F',0};

assemlbey_dude wrote:
What is the maximum number of elements a string can contain?

Code:
string   dc.b  'This is a string',0


Using this same code I placed 266 letters in between the quotation marks and got an error. What is the max value of letters I can put. What effect does changing the .b to .w or .l have if any?

There is no limit on string length. The maximum length of any one line in the source is 256 characters. Just use multiple lines of source to create longer strings. The .B .W and .L syntax creates Byte, Word or Long word data. The data is padded with trailing zeros to make it fill the word or long word.
Code:
00001006= 61 62 63 64 65            14  str1 dc.b 'abcde'
0000100C= 6162 6364 6500            15  str2 dc.w 'abcde'
00001012= 61626364 65000000         16  str3 dc.l 'abcde'

_________________
Prof. Kelly


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 19, 2012 8:02 pm 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
profkelly wrote:
A null terminated string must end with binary 0, $ff does not work as a string terminator.


Naturally, but I think he means that this could be achieved by changing the value in the comparison loop. The programmer gets to define the "standard", and if applied consistently it would work fine.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jan 19, 2012 11:01 pm 
Offline
User avatar

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1102
clive wrote:
Naturally, but I think he means that this could be achieved by changing the value in the comparison loop. The programmer gets to define the "standard", and if applied consistently it would work fine.


In the question a statement was made that $ff worked as a string terminator in the simulator. I just want to make it clear that $ff does not work as a string terminator for any of the trap tasks in the simulator.

_________________
Prof. Kelly


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2012 2:15 am 
Offline

Joined: Fri Dec 16, 2011 12:32 am
Posts: 17
profkelly wrote:
assemlbey_dude wrote:
Thanks for the reply. C uses \0 but this is treated a single character. I just tried modifying a program in the simulator $ff also worked. So, we don't have to use 0 to terminate a string do we.


A null terminated string must end with binary 0, $ff does not work as a string terminator.
Code:
   ORG   $1000
START:    ; first instruction of program

    move.b  #14,d0
    lea string,a1
    trap    #15
    MOVE.B   #9,D0
    TRAP #15  ; halt simulator

* Variables and Strings
string dc.b '0123456789',$ff,'$ff did not work',0
  END  START  ; last line of source


assemlbey_dude wrote:
In C we must use \0 correct?

Code:
string   dc.b  'This is a 0string',0


Will not end before the s since every character(including spaces) inside the single quotation marks is treated as an ASCII character. The 0 in front of the s is written into memory as 48. The 0 after the comma is not converted to its eight bit ASCII representation but is rather converted to its hexadecimal value which is 00. Is all this correct?

Yes, your description of the EASy68K string is correct. In C a null terminated string is created by default when literal strings are used.
Code:
char str[] = "Creates null terminated string";

The null characters may be encoded using \0 or literal 0.
Code:
char str2[] = {'A','B','C','\0'};
char str3[] = {'D','E','F',0};

assemlbey_dude wrote:
What is the maximum number of elements a string can contain?

Code:
string   dc.b  'This is a string',0


Using this same code I placed 266 letters in between the quotation marks and got an error. What is the max value of letters I can put. What effect does changing the .b to .w or .l have if any?

There is no limit on string length. The maximum length of any one line in the source is 256 characters. Just use multiple lines of source to create longer strings. The .B .W and .L syntax creates Byte, Word or Long word data. The data is padded with trailing zeros to make it fill the word or long word.
Code:
00001006= 61 62 63 64 65            14  str1 dc.b 'abcde'
0000100C= 6162 6364 6500            15  str2 dc.w 'abcde'
00001012= 61626364 65000000         16  str3 dc.l 'abcde'



Cleared up a lot for me. The only thing that is unclear to me is your code.

Code:
   ORG   $1000
START:    ; first instruction of program

    move.b  #14,d0
    lea string,a1
    trap    #15
    MOVE.B   #9,D0
    TRAP #15  ; halt simulator

* Variables and Strings
string dc.b '0123456789',$ff,'$ff did not work',0
  END  START  ; last line of source


I'm not familiar with traps. Why is the decimal number 14 moved into d0? Then you move the starting address of the string into a1 correct? What is trap #15? Why do you move the decimal number 9 into d0? Trap #15 once again here you wrote that it halts the simulator. Why do we need two of these traps? I see that only the second string was displayed. So this program just shows that the only way to terminate a string that is to be displayed is with a 0?

Here are three programs:

Code:
 START ORG $1000   

   org $3000
string   dc.b      'How many characters are there in this string?',0
number   ds.b      1

   org $1000
      movea.w   #string,a0
      
myloop   move.b   (a0)+,d1
      cmp.b      #0,d1
      beq      finished
      add.b      #1,d0
      bra      myloop

finished   move.b   d0,number


   STOP    #$2000
   END   START 



This program counts how many characters there are in a string. The string is terminated with a zero. I believe this program has a limitation that it can only count up to 255 characters. I don't understand why, does it have something to do with .b? If there are more than 255 characters contained in the string it wraps around correct(Ie. 320 chars would have a length of 61 since it would count up to 255 and then start over)? If we want to be able to work with strings larger than 255 characters what do we need to change? All the .b to .w or .l ?

Is this line of code the limiting factor?

Code:
add.b      #1,d0


The maximum number we can count up to is 255 using 8 bits. Since 2^8 is 256(0-255). So the string limits is 255 chars.

I changed the .b to .w and it seems to work now.

Code:
add.w      #1,d0


Now the program can handle up to 2^16 65536 character strings?

As you can see below using this method I was able to use $FF as a string terminator. I suppose I could have used any 8 bit number correct?

Code:
START   ORG   $1000

   org $3000
string   dc.b      'How many characters are there in this string?',$ff
number   ds.b      1

   org $1000
      movea.w   #string,a0
      
myloop   move.b   (a0)+,d1
      cmp.b      #$ff,d1
      beq      finished
      add.b      #1,d0
      bra      myloop

finished   move.b   d0,number


   STOP   #$2000
   END   START




Is this how you are suppose to span a string across multiple lines of source code?


Code:
START   ORG   $1000

   org $3000
string   dc.b      'How many characters are there in this string?'
      dc.b      'Lets try to continue this string down here',0
number   ds.b      1

   org $1000
      movea.w   #string,a0
      
myloop   move.b   (a0)+,d1
      cmp.b      #0,d1
      beq      finished
      add.b      #1,d0
      bra      myloop

finished   move.b   d0,number


   STOP   #$2000
   END   START


All this is still one string since the first line was not terminated, correct?


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jan 20, 2012 4:52 am 
Offline

Joined: Mon Jul 26, 2010 11:43 pm
Posts: 198
Location: Aurora, IL
The traps perform Operating System type functions, like printing strings, numbers, etc. Check the Easy68K manuals and help if you are unfamiliar with these.

You need to be clearing D0 before you start. CLR.L D0

I don't think I'd be using MOVEA.W for an address. It might work here, but is prone to fail if you had more code, or integrated it with other code.

Yes, if you use ADD.W #1,D0, or ADD.L #1,D0 your counts will be 16 and 32 bits respectively. You'd need to make the number variable bigger.

Yes, you could technically use other end-of-string markers, the NUL termination method has at least 40 years of usage, and works quite adequately. A lot of programs and OS depend on strings in this format.

Yes, you can span strings in that method, like we illustrated in prior posts.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 01, 2012 4:20 am 
Offline

Joined: Fri Dec 16, 2011 12:32 am
Posts: 17
I would appreciate prof Kelly's input as well.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Feb 01, 2012 12:48 pm 
Offline
User avatar

Joined: Thu Dec 16, 2004 6:42 pm
Posts: 1102
clive wrote:
The traps perform Operating System type functions, like printing strings, numbers, etc. Check the Easy68K manuals and help if you are unfamiliar with these.

You need to be clearing D0 before you start. CLR.L D0

I don't think I'd be using MOVEA.W for an address. It might work here, but is prone to fail if you had more code, or integrated it with other code.

Yes, if you use ADD.W #1,D0, or ADD.L #1,D0 your counts will be 16 and 32 bits respectively. You'd need to make the number variable bigger.

Yes, you could technically use other end-of-string markers, the NUL termination method has at least 40 years of usage, and works quite adequately. A lot of programs and OS depend on strings in this format.

Yes, you can span strings in that method, like we illustrated in prior posts.

There is not much I can add to Clive's comments.

The trap tasks in the EASy68K simulator expect strings that are terminated with zero. As do all of the string manipulation functions in the C language.

From EASy68K help:
"The instruction TRAP pushes the program counter and the status register on the supervisor stack, switches to supervisor mode and the program counter is given a new value taken from one of the sixteen vectors, given by a four bit data value.
The instruction is used in applications to call a supervisor program (an OS for example) without knowing exactly where in the memory the OS is."

TRAP #0 through TRAP #14 vectors are available for program use. TRAP #15 has been designated by the simulator to perform operating system type tasks like display and input.

_________________
Prof. Kelly


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 15 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group