Note that there are some explanatory texts on larger screens.

plurals
  1. POVisual Studio only breaks on second line of assembly?
    primarykey
    data
    text
    <h2>The short description:</h2> <p>Setting a breakpoint on the first line of my <code>.CODE</code> segment in an assembly program will not halt execution of the program.</p> <h2>The question:</h2> <p>What about Visual Studio's debugger would allow it to fail to create a breakpoint at the first line of a program written in assembly? Is this some oddity of the debugger, a case of breaking on a multi-byte instruction, or am I just doing something silly?</p> <h2>The details:</h2> <p>I have the following assembly program compiling and running in Visual Studio:</p> <pre><code>; Tell MASM to use the Intel 80386 instruction set. .386 ; Flat memory model, and Win 32 calling convention .MODEL FLAT, STDCALL ; Treat labels as case-sensitive (required for windows.inc) OPTION CaseMap:None include windows.inc include masm32.inc include user32.inc include kernel32.inc include macros.asm includelib masm32.lib includelib user32.lib includelib kernel32.lib .DATA BadText db "Error...", 0 GoodText db "Excellent!", 0 .CODE main PROC ;int 3 ; &lt;-- If uncommented, this will not break. mov ecx, 6 ; &lt;-- Breakpoint here will not hit. xor eax, eax ; &lt;-- Breakpoint here will. _label: add eax, ecx dec ecx jnz _label cmp eax, 21 jz _good _bad: invoke StdOut, addr BadText jmp _quit _good: invoke StdOut, addr GoodText _quit: invoke ExitProcess, 0 main ENDP END main </code></pre> <p>If I try to set a breakpoint on the first line of the main function, <code>mov ecx, 6</code>, it is ignored, and the program executes without stopping. Only will a breakpoint be hit if I set it on the line after that, <code>xor eax, eax</code>, or any subsequent line.</p> <p>I have even tried inserting a software breakpoint, <code>int 3</code>, as the first line of the function, and it is also ignored.</p> <p>The first thing I notice that is odd: viewing the disassembly after hitting one of my breakpoints gives me the following:</p> <pre><code>01370FFF add byte ptr [ecx+6],bh --- [Path]\main.asm xor eax, eax 00841005 xor eax,eax --- &lt;-- Breakpoint is hit here _label: add eax, ecx 00841007 add eax,ecx dec ecx 00841009 dec ecx jnz _label 0084100A jne _label (841007h) cmp eax, 21 0084100C cmp eax,15h </code></pre> <p>What's interesting here is that the <code>xor</code> is, in Visual Studio's eyes, the first operation in my program. Absent is the line <code>move ecx, 6</code>. Directly above where it thinks my source begins is the line that actually sets <code>ecx</code> to 6. So the actual start of my program has been mangled according to the disassembly.</p> <p>If I make the first line of my program <code>int 3</code>, the line that appears above where my code is in the disassembly is:</p> <pre><code>00F80FFF add ah,cl </code></pre> <p>As suggested in one of the answers, I turned off ASLR, and it looks like the disassembly is a little more stable:</p> <pre><code>.CODE main PROC ;mov ecx, 6 xor eax, eax 00401000 xor eax,eax --- &lt;-- Breakpoint is present here, but not hit. _label: add eax, ecx 00401002 add eax,ecx --- &lt;-- Breakpoint here is hit. dec ecx 00401004 dec ecx </code></pre> <p>The complete program is visible in the disassembly, but the problem still perists. Despite my program starting on an expected address, <strong>and</strong> the first breakpoint being shown in the disassembly, it is still skipped. Placing an <code>int 3</code> as the first line still results in the following line:</p> <pre><code>00400FFF add ah,cl </code></pre> <p>and does not stop execution, <em>and</em> re-mangles the view of my program in the disassembly again. The next line of my program is then at location <code>00401001</code>, which I suppose makes sense because <code>int 3</code> is a one-byte instruction, but why would it have disappeared in the disassembly?</p> <p>Even starting the program using the 'Step Into (F11)' command does not allow me to break on the first line. In fact, with no breakpoint, starting the program with F11 does not halt execution at all.</p> <p>I'm not really sure what else I can try to solve the problem, beyond what I have detailed here. This is stretching beyond my current understanding of assembly and debuggers.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload