0
votes

I've written a program on MASM32 which throws an error, but I see no way to correct it. The program is to replace all elements (symbols) met after the last occurrence of 'a' to '*' in input string, which is entered from the keybord; the input string is no longer than 100 symbols.

The error is following:

 C:\Users\Mikola\AppData\Local\Temp\SASM\program.asm(60) : error A2101: cannot add two relocatable labels

Here's the code

.686P
.model flat, stdcall
option casemap: none

        include c:\masm32\include\windows.inc

        include c:\masm32\include\user32.inc
        include c:\masm32\include\kernel32.inc
        include c:\masm32\include\masm32.inc

        includelib c:\masm32\lib\user32.lib
        includelib c:\masm32\lib\kernel32.lib
        includelib c:\masm32\lib\masm32.lib


.data

mes1      db   'String(1):  '   
mes2      db   'String(2):  '   
mes3      db   'Result...:  '   
len       dd   $ - mes3         
crlf      db   13,10            

buff1     db   100 dup(0)       
buff2     db   100 dup(0)       
size1     dd   0                
size2     dd   0                
bigStr    dd   0,0              
smallStr  dd   0,0              

.code
start:
;------ Запрос и вводим строки
        invoke   WriteConsoleA, 7, mes1, [len], 0,0     
        invoke   ReadConsoleA, 3, buff1, 100, size1,0   

        invoke   WriteConsoleA, 7, mes2, [len], 0,0     
        invoke   ReadConsoleA, 3, buff2, 100, size2,0   

;------ Сравниваем размеры введённых строк
        push     buff1 [size1]    
        push     buff2 [size2]    
        mov      eax,[size1]      
        cmp      eax,[size2]      
        jb       @@small          

        pop      [smallStr] [smallStr+4]   
        pop      [bigStr]   [bigStr+4]     
        jmp      @@big                      

@@small: pop      [bigStr]   [bigStr+4]     
        pop      [smallStr] [smallStr+4]   

;------ Обработка длинной строки (меняем все/строчные на (N mod 10))
@@big:   mov      ecx,[bigStr]     
        mov      esi,[bigStr+4]   
        mov      edi,esi          
        xor      ebx,ebx          
@@cyc1:  lodsb                    
        inc      bl               
        cmp      al,'a'           
        jb       @@next1          
        cmp      al,'z'           
        ja       @@next1          
        mov      al,bl            
        aam                       
@@next1: stosb                    
        loop     @@cyc1            

;------ Обработка короткой строки (после последнего 'a', все на '*')
        mov      ecx,[smallStr]   
        dec      cx
        push     ecx              
        mov      edi,[smallStr+4] 
        add      edi,ecx          
        mov      al,'a'           
        std                       
@@cyc2:  repne    scasb            
        cld                       
        pop      eax              
        or       ecx,ecx          
        jz       @@stop           

        xchg     ecx,eax          
        sub      ecx,eax          
        add      edi,2            
        mov      al,'*'           
        rep      stosb            

;------ Вывод результата из буфера
@@stop:  invoke   WriteConsoleA, 7, mes3, [len],   0,0
        invoke   WriteConsoleA, 7, buff1,[size1], 0,0
        invoke   WriteConsoleA, 7, crlf,2,0,0          
        invoke   WriteConsoleA, 7, mes3, [len],   0,0
        invoke   WriteConsoleA, 7, buff2,[size2], 0,0

        jmp      $                
@@exit:  invoke  ExitProcess, 0    

end start
1
Because you can't do things like buff1 [size1] when size and buff1 are labels. You are taking two relocatable labels and trying to add them together.You would need to move the value located at size1 into a register and then use that register inside the square brackets. - Michael Petch
like this? mov eax, [size1] push buff1 [eax] - Мiкола Нечiпорук

1 Answers

-2
votes

(sorry, misread the question, I think this is valid though): The loop instruction decrements ecx before checking the condition. In your code, you never set the string length (bigStr+0, smallStr+0), so ecx is initially 0. Thus your program will attempt to process 2^32 characters before loop will stop it.

If you use loop, you must check the pre-condition first, as in:

if (i) {
     do {
         x[i] = tolower(x[i]);
     } while (--i);
}