<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>tag:blog.danieljanus.pl,2019:category:assembly</id>
  <title>Daniel Janus – assembly</title>
  <link href="http://blog.danieljanus.pl/category/assembly/"/>
  <updated>2014-04-06T00:00:00Z</updated>
  <author>
    <name>Daniel Janus</name>
    <uri>http://danieljanus.pl</uri>
    <email>dj@danieljanus.pl</email>
  </author>
  <entry>
    <id>tag:blog.danieljanus.pl,2014-04-06:post:dos-debugging-quirk</id>
    <title>DOS debugging quirk</title>
    <link href="http://blog.danieljanus.pl/dos-debugging-quirk/"/>
    <updated>2014-04-06T00:00:00Z</updated>
    <content type="html">&lt;div&gt;&lt;p&gt;While hacking on Lithium, I’ve noticed an interesting thing. Here’s a sample DOS program in assembly (TASM syntax):&lt;/p&gt;&lt;pre&gt;&lt;code class="hljs x86asm"&gt;&lt;span class="hljs-meta"&gt;.model&lt;/span&gt; tiny
&lt;span class="hljs-meta"&gt;.code&lt;/span&gt;
  org &lt;span class="hljs-number"&gt;100h&lt;/span&gt;

N &lt;span class="hljs-built_in"&gt;equ&lt;/span&gt; &lt;span class="hljs-number"&gt;2&lt;/span&gt;
&lt;span class="hljs-symbol"&gt;
start:&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; &lt;span class="hljs-built_in"&gt;bp&lt;/span&gt;,&lt;span class="hljs-built_in"&gt;sp&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; &lt;span class="hljs-built_in"&gt;ax&lt;/span&gt;,&lt;span class="hljs-number"&gt;100&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; [&lt;span class="hljs-built_in"&gt;bp&lt;/span&gt;-N],&lt;span class="hljs-built_in"&gt;ax&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; &lt;span class="hljs-built_in"&gt;cx&lt;/span&gt;,[&lt;span class="hljs-built_in"&gt;bp&lt;/span&gt;-N]
  &lt;span class="hljs-keyword"&gt;cmp&lt;/span&gt; &lt;span class="hljs-built_in"&gt;cx&lt;/span&gt;,&lt;span class="hljs-built_in"&gt;ax&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;jne&lt;/span&gt; wrong
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; &lt;span class="hljs-built_in"&gt;dx&lt;/span&gt;,offset msg
  &lt;span class="hljs-keyword"&gt;jmp&lt;/span&gt; disp
&lt;span class="hljs-symbol"&gt;wrong:&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; &lt;span class="hljs-built_in"&gt;dx&lt;/span&gt;,offset msg2
&lt;span class="hljs-symbol"&gt;disp:&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; &lt;span class="hljs-number"&gt;ah&lt;/span&gt;,&lt;span class="hljs-number"&gt;9&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;int&lt;/span&gt; &lt;span class="hljs-number"&gt;21h&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;mov&lt;/span&gt; &lt;span class="hljs-built_in"&gt;ax&lt;/span&gt;,&lt;span class="hljs-number"&gt;4c00h&lt;/span&gt;
  &lt;span class="hljs-keyword"&gt;int&lt;/span&gt; &lt;span class="hljs-number"&gt;21h&lt;/span&gt;

msg &lt;span class="hljs-built_in"&gt;db&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;ok$&amp;quot;&lt;/span&gt;
msg2 &lt;span class="hljs-built_in"&gt;db&lt;/span&gt; &lt;span class="hljs-string"&gt;&amp;quot;wrong$&amp;quot;&lt;/span&gt;
end start
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you assemble, link and then execute it normally, typing &lt;code&gt;prog&lt;/code&gt; in the DOS command line, it will output the string “ok”. But if you trace through the program in a debugger instead, it will say “wrong”! What’s wrong?&lt;/p&gt;&lt;p&gt;The problem is in lines 10-11 (instructions 3-4). Here’s what happens when you trace through this program in DOS 6.22’s &lt;code&gt;DEBUG.EXE&lt;/code&gt;:&lt;/p&gt;&lt;img src="/img/blog/debug.png"&gt;
&lt;p&gt;Note how in instruction 3 (actually displayed as the second above) we set the word &lt;code&gt;SS:0xFFFC&lt;/code&gt; to &lt;code&gt;100&lt;/code&gt;. When about to execute the following instruction, we would expect that word to continue to hold the value &lt;code&gt;100&lt;/code&gt;, because nothing which could have changed that value has happened in between. Instead, the debugger still reports it as &lt;code&gt;0x0D8A&lt;/code&gt;, as if instruction 3 had not been executed at all — and, interestingly, after actually executing this instruction, &lt;code&gt;CX&lt;/code&gt; gets yet another value of &lt;code&gt;0x7302&lt;/code&gt;!&lt;/p&gt;&lt;p&gt;Normally, thinking of DOS &lt;code&gt;.COM&lt;/code&gt; programs, you assume a 64KB-long chunk of memory that the program has all to itself: the code starts at &lt;code&gt;0x100&lt;/code&gt;, the stack grows from &lt;code&gt;0xFFFE&lt;/code&gt; downwards (at any given time, the region from &lt;code&gt;SP&lt;/code&gt; to &lt;code&gt;0xFFFE&lt;/code&gt; contains data currently on the stack), and all memory in between is free for the program to use however it deems fit. It turns out that, when debugging, it is not the case: the debuggers need to manipulate the region just underneath the program’s stack in order to handle the tracing/breakpoint interrupt traps.&lt;/p&gt;&lt;p&gt;I’ve verified that both DOS’s DEBUG and Borland’s Turbo Debugger 5 do this. The unsafe-to-touch amount of space below SP that they need, however, varies. Manipulating the N constant in the original program, I’ve determined that DEBUG only needs 8 bytes below SP, whereas for TD it is a whopping 18 bytes.&lt;/p&gt;&lt;/div&gt;</content>
  </entry>
</feed>
