Hi
If I have defined 10 bits, say - word db 10 DUP (?)
And I run my program when there is less than 10 characters for example 8, the remaining two characters from the last time the program was run are displayed.
How do I only display 8 characters with the remaining two blank if I have defined 10?
Thanks
Windows recognises the end of a string when it meets a 0 byte. So you must somehow poke a 0 after your 8th byte. If we saw your complete code, or at least the part that loads the dup 10, we could give advice...
Some of the Windows function do require that a string must contain a "0" to indicate where it terminates. Such strings are called null-terminated strings. In the old DOS days, the required terminating character used to be the "$" character for some of the DOS functions.
However, other Windows functions (and some DOS functions) require that the number of characters to be processed must be explicitely provided as a parameter. As jj2007 indicated, a bit more of your code where you attempt to display your string would definitely help us in helping you.
Thanks
This code is supposed to input a word or message and code it by decrementing the first letter by 1 and the 2nd letter by two etc
I have not grasped the repeat function yet, so this is a little long winded but it appears to work, but if i type a letter less than 9 letters the program outputs the characters held in the remaining memory space from the last time the program was run.
Ideally the program needs to stop coding once the counter = the number of characters entered by the user.Â
.486
.model flat, stdcall
option casemap:none
include c:\masm32\work\headings.inc   Â
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.data
 Â
  request   db "Type a word (Maximum of 9 letters) that you would like coding & press enter",13,10,0  ; screen output
.data?
  word1    db   9 dup(?)                   ; space allocated for word to be entered
  word2    dword  9 dup(?)                   ; space allocated for
  clock    db   1  dup(?)                   ; space allocated for
 Â
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.code
main proc
    mov ecx,0
    mov ebx,0
    mov eax,0
Â
    invoke   StdOut,   ADDR request                   ; display request on screen
    invoke   StdIn,   ADDR word1,LENGTHOF word1       ; allow 9 bit word to be entered
       Â
    mov     ecx,    offset word1              ; move offset address of entered word to edx
    mov     ebx,    offset word2              ; move offset address of word 2 to ebx
    mov     clock,  1                       ; set clock to 1
         Â
    mov ecx, offset word1
    mov ebx, offset word2
  Â
    mov ax, [ecx]
    sub al, clock
    mov [ebx],al
    inc clock
    mov ax, [ecx+1]
    sub al, clock
    mov [ebx+1],al
    inc clock
    mov ax, [ecx+2]
    sub al, clock
    mov [ebx+2],al
    inc clock
    mov ax, [ecx+3]
    sub al, clock
    mov [ebx+3],al
    inc clock
    mov ax, [ecx+4]
    sub al, clock
    mov [ebx+4],al
    inc clock
    mov ax, [ecx+5]
    sub al, clock
    mov [ebx+5],al
    inc clock
    mov ax, [ecx+6]
    sub al, clock
    mov [ebx+6],al
    inc clock
    mov ax, [ecx+7]
    sub al, clock
    mov [ebx+7],al
    inc clock
    mov ax, [ecx+8]
    sub al, clock
    mov [ebx+8],al
    inc clock
    print "This is your coded word",13,10
    invoke StdOut,ADDR word2                    ;display result on screen    Â
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
invoke ExitProcess,0
main endp
end main                          ; Tell MASM where the program ends
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
StdIn will trim the input to the length specified, if necessary, and then add a null terminator. To avoid having this null terminator overwrite the next byte after the buffer, the length specified in the call to StdIn must be at least one byte less than the length of the buffer. As coded your buffers have a length of 9 bytes and LENGTHOF is returning 9. Since the return value for LENGTHOF acts as a constant, you can do arithmetic on it within the instruction statement (e.g. LENGTHOF word1 - 1)
Your code is copying 9 bytes to the output regardless of the number of characters (bytes) entered. You can determine when you have reached the end of the input by checking for the null terminator.
StdOut expects the string to be null-terminated, so you need to add a null terminator at the end of the encoded string.
Instead of handling each byte of the input in separate blocks of code, it would be more efficient to do it in a loop. As pseudo code:
p1 = 32-bit register that contains the address of the input buffer
p2 = 32-bit register that contains the address of the output buffer
cnt = 32-bit register that initially contains the value 1
startofloop:
 get input byte (e.g. mov al, [p1+cnt-1])
 test the value of the byte and if it is zero exit the loop
 encode the byte by subtracting the low-order byte of cnt from it
 store the byte in the output buffer
 increment cnt
 store a null terminator at the end of the output buffer (e.g. mov BYTE PTR [p2+cnt-1], 0)
repeat the loop
The step that stores the null terminator at the end of the output buffer within the loop makes the code simpler. If the next byte from the input buffer is the null terminator then the null terminator for the output buffer will be in place. Otherwise the null terminator for the output buffer will be overwritten with the next encoded byte and the process will continue.
Thanks
I have managed to loop the program using the repeat function but when I try to while the output register it does not work. The code as displayed does code a word but again does not nullify.
If I try the byte ptr(which from what I understand allows different size data to move to normally restricted data size registers) i get errors.
Matt
.data
MsgBoxText db "Press OK Then Type a word (Maximum of 9 letters) that you would like coding & press Enter",0
MsgCaption db " London SouthBank University Microprocessors ",0
.data?
p1 db 31 dup(0) ; space allocated for word to be entered
p2 dword 32 dup(0) ; space allocated for
cnt db 1 dup(0) ; space allocated for
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.code
main proc
invoke MessageBox, NULL,addr MsgBoxText, addr MsgCaption, MB_OK
invoke StdIn, ADDR p1,LENGTHOF p1 ; allow 32 bit word to be entered
mov ecx, offset p1 ; move offset address of entered word to edx
mov ebx, offset p2 ; move offset of allocated space for coded to ebx
mov cnt,1
mov p2,0
mov ecx, offset p1
mov ebx, offset p2
.repeat ;while the al register is less than 0 follow code
mov ax,[ecx+esi] ;mov address of ecx + esi to ax register
sub al, cnt ;subtract value of cnt from al register
mov [ebx+esi],al ;mov value of al to address of ebx +esi (P2 to display)
inc cnt ;increment counter
inc esi ;increment esi
.until al==0
print "This is your coded word",13,10
invoke StdOut,ADDR p2 ;display result on screen
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
invoke ExitProcess,0
main endp
end main ; Tell MASM where the program ends
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Quotep1    db   31 dup(0)
Because you should retain one byte for a terminating 0, that would allow only 30 bytes of input (and not 32). One suggestion for retaining the full buffer size for input could be:
p1    db   32 dup(0)
p1_0   db   0
Quotep2    dword  32 dup(0)
Since you are going to use this variable for a string no larger than that in p1, there is no need to declare that variable as dword. It should be declared as bytes like p1.
You are using the ESI register as an incremental counter for the pointer into the string. However, that register cannot be expected to have a value of 0 when your program starts (NONE of the registers are expected to have a reliable value when the program starts). Rezero that ESI register before the .repeat loop and you should have better results.
Quotemov ax,[ecx+esi]
Because you are processing only one byte at a time (the one in the AL register), there is no need to get two bytes from memory into the AX register.