注册 登录
编程论坛 汇编论坛

变量不管用

nooomoon 发布于 2015-09-02 11:53, 4816 次点击
我是一个初学者。打算从最简单的功能学起。按书上的程序输入,然后调试。
发现定义的变量没有用。变量相应地址的数据不是程序中的。
网上查了一下。原来在程序运行之后,还要有代码要定义数据段什么的。可能要初始化。
这些代码要怎么写。都是什么原理。有人懂吗?可能一般人不懂。用INCLUE一些库还是什么也可以解决。
我想知道在程序代码运行之前的那些初始化数据的汇编代码。也不知在程序代码运行之前还有无什么其它的隐藏的事情要做。请教。多谢!
15 回复
#2
zklhp2015-09-02 12:02
我的问题是:你的书是哪本 你有没有书上说的环境 或者你有没有按照书上说的去做

如果你的书上没有明确说到底应该怎么做 我感觉可以换一本讲的更清楚的书

至于你后面「网上查」的东西可能就南辕北辙了 因为网上的资料很可能不是针对你的书的

祝你学习愉快
#3
nooomoon2015-09-02 12:07
就是Irvine写的Inter汇编程序设计。里面最开始的代码。我把INCLUDE Irvine16.inc一行去掉了。
因为不懂怎么Link这些库。然后。程序调试的时候。定义的变量就不管用。其余的代码还是可以正常工作。
#4
wp2319572015-09-02 14:02
完全不懂你在说什么
#5
nooomoon2015-09-02 15:35
原来程序是
INCLUDE Irvine32.inc
.data
val1 DWORD 10000h

.code
main PROC
    mov eax,val1
    exit
main ENDP
END main
我把INCLUDE Irvine32.inc去掉了。DEBUG发现val1的值没有到eax寄存器。从译编的结果来看,val1的地址已经有了。但是那个内存地址的值不是10000h。可能是要有一段什么代码。把数据段的值放到那个内存地址。那段代码是啥?希望有人能解答。谢谢。
#6
hu9jj2015-09-02 20:27
原来句号可以这样用,开眼界了。
#7
hu9jj2015-09-02 20:29
以下是引用nooomoon在2015-9-2 11:53:25的发言:

我是一个初学者。打算从最简单的功能学起。按书上的程序输入,然后调试。
发现定义的变量没有用。变量相应地址的数据不是程序中的。
网上查了一下。原来在程序运行之后,还要有代码要定义数据段什么的。可能要初始化。
这些代码要怎么写。都是什么原理。有人懂吗?可能一般人不懂。用INCLUE一些库还是什么也可以解决。
我想知道在程序代码运行之前的那些初始化数据的汇编代码。也不知在程序代码运行之前还有无什么其它的隐藏的事情要做。请教。多谢!

除了两个逗号、一个问号和一个感叹号外,其他全是句号。
#8
nooomoon2015-09-03 09:53
以下是引用hu9jj在2015-9-2 20:29:04的发言:

 
除了两个逗号、一个问号和一个感叹号外,其他全是句号。
此回复奇也怪哉。余所问者 代码事耳 尔所见者 符号事矣
余所用标点符号,乃中文古法。现代标点源自西夷。古文未有标点。有注释者。以朱笔圈点断句。以便阅读。
又因白话文故,之乎者也矣焉哉不用。以夷之感叹号、问号代之。故有此标点之法。以便阅读。
读之者,不以文害辞,不以辞害意。可知吾文之所指。当不以此标点为怪。吾未尝见有以吾标点为异者。
今尔以为怪。故告之来去始末。有不妥之处,望予以指正。为谢。

#9
nooomoon2015-09-03 10:07
以下是引用zklhp在2015-9-2 12:02:13的发言:

我的问题是:你的书是哪本 你有没有书上说的环境 或者你有没有按照书上说的去做

如果你的书上没有明确说到底应该怎么做 我感觉可以换一本讲的更清楚的书

至于你后面「网上查」的东西可能就南辕北辙了 因为网上的资料很可能不是针对你的书的

祝你学习愉快

君之指教,于吾有助也。深以为谢。在下读书太快。捡书中代码以试。不能。见君之回复。细查吾书。知书中已有其法矣。
加此二句即可
mov ax,@data
mov ds,ax
程序运行之无误。
余调试之时,见其第一句mov程序之数据段地址入ax。深以为怪。此程序者,固有文件之代码。彼数据地址者,因机器因时而常变。
固有文件焉知?余思之。必操作系统改此第一句。又以hex编码查二进制执行文件。代码段机器码第一字节为b8。移一固有16位数进ax。
而执行之时,操作系统取此一指令,改操作数为数据段内存地址,写入内存中之代码段。操作系统如何运用此一句。又如何改之。余不知矣。望有知之者告之。为谢
#10
wmf20142015-09-03 11:03
回复 9楼 nooomoon
不是操作系统取此指令,是cpu取此指令。“mov ax,@data”是汇编码,意思是取变量data所在内存区域的段地址到ax寄存器中。汇编代码需要经过编译后成为机器码才能供cpu执行,至于data所在的段地址是多少,需要exe文件重定位后确定。exe文件头会在系统加载后从系统获取一个起始段地址,以这个段地址为基础,定位所有需要浮动的地址(包括跳转、栈等),com类型文件不需要此句。加入编译后的文件加载后数据段地址为1000H,则对应的机器码为"B8 00 10",其中B8为指令,“00 10”为该指令所需要的数据,cpu从内存中取得b8指令后,就会自动从指令后内存中再取两个字节数据,然后把这两个字节数据送到寄存器ax中,这条指令就执行完毕。大概如此了,如果你学过数字脉冲电路,你就比较好理解这个操作过程在电路上是如何操作的,无非是计数器、寄存器、译码器等电路按时序工作而已。
#11
nooomoon2015-09-03 11:59
以下是引用wmf2014在2015-9-3 11:03:02的发言:

不是操作系统取此指令,是cpu取此指令。“mov ax,@data”是汇编码,意思是取变量data所在内存区域的段地址到ax寄存器中。汇编代码需要经过编译后成为机器码才能供cpu执行,至于data所在的段地址是多少,需要exe文件重定位后确定。exe文件头会在系统加载后从系统获取一个起始段地址,以这个段地址为基础,定位所有需要浮动的地址(包括跳转、栈等),com类型文件不需要此句。加入编译后的文件加载后数据段地址为1000H,则对应的机器码为"B8 00 10",其中B8为指令,“00 10”为该指令所需要的数据,cpu从内存中取得b8指令后,就会自动从指令后内存中再取两个字节数据,然后把这两个字节数据送到寄存器ax中,这条指令就执行完毕。大概如此了,如果你学过数字脉冲电路,你就比较好理解这个操作过程在电路上是如何操作的,无非是计数器、寄存器、译码器等电路按时序工作而已。

多谢指教 程序编成exe文件后 我用二进制编辑器查看文件 文件代码的第一条指令是b8 04 00
然后用debug把程序加载进内存
用d命令查看内存中的代码段
这条指令变成b8 60 07
CPU要执行的就是b8 60 07
0760就是数据段地址。
那个b8 04 00不知去哪里了 如果cpu执行这条 也是把0004这个放到ax里面 显然是操作系统没有把硬盘中二进制执行文件exe的代码段直接拷进内存 而是改变了第一条指令的操作数为分配的内存数据段地址 我估计有个exe文件头里面有个什么东西 让操作系统把数据段地址送到b8后面2个字节


[ 本帖最后由 nooomoon 于 2015-9-3 12:00 编辑 ]
#12
wmf20142015-09-03 12:16
回复 11楼 nooomoon
我在10楼说了,EXE类型文件属于浮动代码可执行文件,系统加载后需要重定位,该类型文件头记录了需要重定位的数据位置,你文件的数据位"b8 00 04",加载后“00 04”就重定位成“60 07”了,说明加载该文件时,系统给你的基础段地址为075c,重定位执行075c+0004的操作。COM类型文件不需要此类操作。
#13
nooomoon2015-09-03 19:22
以下是引用wmf2014在2015-9-3 12:16:52的发言:

我在10楼说了,EXE类型文件属于浮动代码可执行文件,系统加载后需要重定位,该类型文件头记录了需要重定位的数据位置,你文件的数据位"b8 00 04",加载后“00 04”就重定位成“60 07”了,说明加载该文件时,系统给你的基础段地址为075c,重定位执行075c+0004的操作。COM类型文件不需要此类操作。
多谢您指点。在下查了有关资料。和您10楼所言略有不同。exe文件在加载过程中需要重定位。操作系统先将头文件载入内存。根据头文件的记录给程序分配内存和基地址。把程序载入内存中。还要根据头文件,找到重定位表,根据重定位表找到需要重定位的条目。把载入内存的程序中需要重定位的条目按你说的方法计算后,替换原有的条目。然后设置SS,SP,ES,CS寄存器的值。然后IP指向程序的第一条指令。其中还有些过程略过。
这就是为什么内存中的程序和文件中的程序不同。程序重定位表中的条目,在载入内存中后会被修改。然后再执行。


[ 本帖最后由 nooomoon 于 2015-9-3 19:23 编辑 ]
#14
zhulei19782016-04-10 07:35
以下是引用nooomoon在2015-9-3 09:53:20的发言:

此回复奇也怪哉。余所问者 代码事耳 尔所见者 符号事矣
余所用标点符号,乃中文古法。现代标点源自西夷。古文未有标点。有注释者。以朱笔圈点断句。以便阅读。
又因白话文故,之乎者也矣焉哉不用。以夷之感叹号、问号代之。故有此标点之法。以便阅读。
读之者,不以文害辞,不以辞害意。可知吾文之所指。当不以此标点为怪。吾未尝见有以吾标点为异者。
今尔以为怪。故告之来去始末。有不妥之处,望予以指正。为谢。


强啊,现在估计没人这么说话了
#15
zhulei19782016-04-10 07:49
以下是引用nooomoon在2015-9-3 19:22:20的发言:

多谢您指点。在下查了有关资料。和您10楼所言略有不同。exe文件在加载过程中需要重定位。操作系统先将头文件载入内存。根据头文件的记录给程序分配内存和基地址。把程序载入内存中。还要根据头文件,找到重定位表,根据重定位表找到需要重定位的条目。把载入内存的程序中需要重定位的条目按你说的方法计算后,替换原有的条目。然后设置SS,SP,ES,CS寄存器的值。然后IP指向程序的第一条指令。其中还有些过程略过。
这就是为什么内存中的程序和文件中的程序不同。程序重定位表中的条目,在载入内存中后会被修改。然后再执行。


[ 本帖最后由 nooomoon 于 2015-9-3 19:23 编辑 ]


文件中的程序是静态的,内存中的程序是动态的,是在运行的
#16
Valenciax2016-06-11 21:32
贴子很旧了,但也想回一下

5楼的原程式没有错
若有Irvine32.inc,并INCLUDE进来
Irvine32.inc包括了许多32bit程式的细节/lib等设定
楼主这段代码,编译器会为它编译成32bit程式,只能在window下运行,
那时候cs,ds等段暂存器[不需要],直接mov eax,val1就拿到资料

但若没有Irvine32.inc
编译器只当它是普通的16bit Dos程式,ds段暂存器[必须]赋值,
否则无法取得ds段里val1的值
1