u654f 发表于 2012-8-30 00:35:49

汇编实验12求助

本帖最后由 u654f 于 2012-8-30 00:37 编辑

assume cs:code
code segment
start:
;注册子程序
mov ax,cs
mov ds,ax   ;设置源地址为代码段
mov si,offset pregstart

mov ax,0h
mov es,ax   ;设置一个安全的目标地址
mov di,200h

mov cx,offset pregend-offset pregstart
cld   ;设置递增
rep movsb ;传送字串

mov ax,0
mov es,ax
mov word ptr es:,200h
mov word ptr es:,0       ;设置中断向量表
;程序结束

mov ax,4c00h
int 21h
;子程序
pregstart:
jmp short maincode
data:
db 'Hello world!',0
maincode:
mov ax,cs
mov ds,ax
mov si,offset data

mov ax,0b800h
mov es,ax
mov di,12*160+36*2
mov cx,13

childcode:
   mov dh,0
   mov dl,
   mov al,
   mov es:,al
   inc si
   add di,1
   mov al,02h
   mov es:,al
   add di,1
   mov cx,dx
   jcxz endflag
   jmp short childcode
endflag:
mov ax,4c00h
int 21h


pregend:nop
code ends
end start
看上面红色加粗的代码,为什么这样写不行?如果换成mov si,202h是可以的或者写成 mov si,200h+offset data-offset pregstart也是可以的

lukelqz 发表于 2012-8-30 00:35:50

mov si,offset data
data是相对于安装程序的偏移(你可以用debug查看一下),你把安装程序复制到0:200H处,字符串的si已经定位不到字符串了,由于jmp short maincode占用了2个字节,所以字符串的地址必须从202h开始,你不管用offset什么,si等于202h就行,这样就可以定位到字符串。

http://bbs.fishc.com/thread-20960-1-6.html看六楼

GeV20 发表于 2012-8-30 10:43:34

本帖最后由 GeV20 于 2012-8-30 11:24 编辑

没有仔细去调试,只是想提点疑问:
mov si,offset data 这句中data是多少?应该是相对于原来的安装程序的位置对吧,安装以后这个数值就不适合新位置使用了.在程序编译的时候offset data,offset offset pregstart 这些都已经定下来了,DEBUG时应该再看不到这些符号,取而代之的是具体的数值,在代码被拷贝到新地方后,这个值不会变,显然它所指向的地方已经不对了.
改成这种形式应该没问题 mov si,202h(具体数值没详究)
mov si,200h+offset data-offset pregstart这也可以,因为编译时算好了而且是相对值,本质上跟上面那个一样



u654f 发表于 2012-9-1 22:13:39

本帖最后由 u654f 于 2012-9-1 22:16 编辑

lukelqz 发表于 2012-9-1 17:27 http://bbs.fishc.com/static/image/common/back.gif
mov si,offset data
data是相对于安装程序的偏移(你可以用debug查看一下),你把安装程序复制到0:200H处 ...

你的意思应该跟2楼的差不多,如果你说的是对的,那下面的两句
jcxz endflag
jmp short childcode
也应该是相对于安装程序的偏移地址 ,照理说就算把mov si,offset data 换成mov si,202h也不应该会正常显示才对啊。

lukelqz 发表于 2012-9-1 22:31:33

u654f 发表于 2012-9-1 22:13 http://bbs.fishc.com/static/image/common/back.gif
你的意思应该跟2楼的差不多,如果你说的是对的,那下面的两句
jcxz endflag
jmp short childcode


跳转指令都是相对位移,不是绝对位移。和offset不同哦。jcxz endflag是endflag相对于jcxz指令的位移差。所以你不论移到哪儿,都可以正确寻址。你用debug看看就知道了

GeV20 发表于 2012-9-1 22:33:22


跳转指令比较特别,翻译成机器指令后是向前或后要跳过多少距离,而不是要跳到某个位置.你问的都是关于重定位问题

GeV20 发表于 2012-9-1 22:39:18

关于跳转指令,"实验8:分析一个奇怪的程序"比较有意思

迷失的自我 发表于 2012-9-6 13:14:18

程序是先全部被转换为机器码再执行的
例子中,红色部分会被翻译成BE2F00,即mov si,002F
程序实现的是将子程序装入到指定地址,而装入的是BE2F00,即偏移为2F,与实际不同,所以出现错误
页: [1]
查看完整版本: 汇编实验12求助