Exception when the program is removing characters from the specified text


Task: write a program to remove the central character in all words of odd length in a given text. I did this (the idea of ​​the algorithm is to find and write the indexes by which the space is located (in the first cycle) and then rewrite the string with missing characters where necessary):

    .model flat, C
    option casemap: none
include c:\masm32\include\msvcrt.inc
include c:\masm32\include\kernel32.inc
includelib c:\masm32\lib\msvcrt.lib
includelib c:\masm32\lib\kernel32.lib
    printf PROTO C, :VARARG
        src         db 'hello masm32_ wrld lb 7',0
        len         equ $-src
        dest        db ' ',len dup(0),0
        end_index   db len/2 dup(0)
        msg2        db ' %d ', 0 
        count_1     db 0
        count_2     db 0
        symbol      equ ' '
        xor ecx,ecx
        xor ebx,ebx
        lea esi,src
        dec ebx     
        inc ebx     
        cmp byte ptr [esi],symbol
        jnz notfound
        inc ecx
        mov byte ptr [end_index + ecx], bl
        inc esi
        cmp byte ptr [esi],0
        jz exit
        jmp next
        lea esi, src
        lea edi, dest
        mov ebx, 1
        xor ecx, ecx
.if byte ptr [end_index + ebx] == 0
        jmp @@_ret
        mov al, byte ptr [end_index + ebx]
        mov ah, byte ptr [end_index + ebx - 1]
        sub al, ah
        xor ah, ah
        push ebx
        mov bl, 2
        div bl
        pop ebx
        add al,  byte ptr [end_index + ebx - 1]
        and eax, 000000ffh      
.if al == cl
        inc count_1
        inc count_2
        inc ebx 
        jmp @@_next
        mov al, byte ptr [esi + count_1]
        mov byte ptr [edi + count_2], al
        inc count_1
        inc count_2
        jmp @@_next
        invoke printf, offset dest , 0
end start

But at the first pass of the loop I get

An exception was thrown at address 0x00042092 in asm_7_deb.exe: 0xC0000005: Read access violation at address 0x0008A045.


00042020  xor         ecx,ecx  
00042022  xor         ebx,ebx  
00042024  lea         esi,[src (045000h)]  
0004202A  dec         ebx  
0004202B  inc         ebx  
0004202C  cmp         byte ptr [esi],20h  
0004202F  jne         _start+18h (042038h)  
00042031  inc         ecx  
00042032  mov         byte ptr end_index (045032h)[ecx],bl  
00042038  inc         esi  
00042039  cmp         byte ptr [esi],0  
0004203C  je          _start+20h (042040h)  
0004203E  jmp         _start+0Bh (04202Bh)  
00042040  lea         esi,[src (045000h)]  
00042046  lea         edi,[dest (045018h)]  
0004204C  mov         ebx,1  
00042051  xor         ecx,ecx  
00042053  cmp         byte ptr end_index (045032h)[ebx],0  
0004205A  jne         _start+3Eh (04205Eh)  
0004205C  jmp         _start+8Ch (0420ACh)  
0004205E  mov         al,byte ptr end_index (045032h)[ebx]  
00042064  mov         ah,byte ptr [ebx+45031h]  
0004206A  sub         al,ah  
0004206C  xor         ah,ah  
0004206E  push        ebx  
0004206F  mov         bl,2  
00042071  div         al,bl  
00042073  pop         ebx  
00042074  add         al,byte ptr [ebx+45031h]  
0004207A  and         eax,0FFh  
0004207F  cmp         al,cl  
00042081  jne         _start+72h (042092h)  
00042083  inc         byte ptr [count_1 (045045h)]  
00042089  inc         byte ptr [count_2 (045046h)]  
0004208F  inc         ebx  
00042090  jmp         _start+33h (042053h)  
00042092  mov         al,byte ptr count_1 (045045h)[esi]  ; <==== probably it happend here
00042098  mov         byte ptr count_2 (045046h)[edi],al  ;           but i do not understand why 
0004209E  inc         byte ptr [count_1 (045045h)]  
000420A4  inc         byte ptr [count_2 (045046h)]  
000420AA  jmp         _start+33h (042053h)  
000420AC  push        0  
000420AE  push        offset dest (045018h)  
000420B3  call        _printf (041005h)  
000420B8  add         esp,8  
000420BB  ret
asked on Stack Overflow Oct 10, 2020 by Gaurav Goswami

1 Answer


In order to load [esi + count_1] you need to load the value of count_1 into a register first. Otherwise it takes the address of count_1 plus the value of esi, which is not what you want.

Since count_1 is a byte, use:

movzx edx, byte ptr [count_1]
mov al, [esi+edx]
answered on Stack Overflow Oct 10, 2020 by prl

User contributions licensed under CC BY-SA 3.0