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

jmp near ptr s

admin_xyz 发布于 2012-09-02 20:12, 2323 次点击
程序代码:
assume cs:code
code segment
start:
    mov        ax, 0
    jmp        near ptr s
    db        32739 dup ('s')        ;  最多向前越过 32768 向后 32767,可是这写32769也能编译通过。求解
s:
    inc        ax
  
    mov        ax, 4c00h
    int        21h
code ends
end start
27 回复
#2
有容就大2012-09-02 21:09
同求
#3
zklhp2012-09-02 21:24
我回复一下楼主肯定会给我分的
#4
admin_xyz2012-09-02 21:28
回复 3楼 zklhp
好歹看两眼么。。。
#5
zklhp2012-09-02 21:40
看了 没看明白。。

near跳转就和有符号字的范围是一样的 按理这样写是错误的 但从反汇编来看是对的 能实现

难道书上错了 搞不懂了
#6
有容就大2012-09-02 21:48
试了下 比32768大一点可以 如果大很多就会出错 也不解~~
#7
zklhp2012-09-02 21:52
程序代码:

assume cs:code
code segment
start:
    mov        ax, 0
    jmp        near ptr s
b:
    mov        ax, 4c00h
    int        21h
    db        65000 dup ('s')        ;  最多向前越过 32768 向后 32767,可是这写32769也能编译通过。求解
s:
    inc        ax
    jmp near ptr b
    mov        ax, 4c00h
    int        21h
code ends
end start


可能编译器很聪明把它弄好了罢
#8
zklhp2012-09-02 21:55
A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly
 code, but at the machine code level, it is encoded as a signed 8-, 16-, or 32-bit
 immediate value. This value is added to the value in the EIP register. (Here, the EIP
 register contains the address of the instruction following the JMP instruction). When
 using relative offsets, the opcode (for short vs. near jumps) and the operand-size
 attribute (for near relative jumps) determines the size of the target operand (8, 16,
 or 32 bits).

手册上这样说的 那么 就是编译器比较聪明的实现了

或许书上说的是错的。。。 不知道了
#9
zklhp2012-09-02 21:56
Near and Short Jumps. When executing a near jump, the processor jumps to the
 address (within the current code segment) that is specified with the target operand.
 The target operand specifies either an absolute offset (that is an offset from the base
 of the code segment) or a relative offset (a signed displacement relative to the
 current value of the instruction pointer in the EIP register). A near jump to a relative
 offset of 8-bits (rel8) is referred to as a short jump. The CS register is not changed on
 near and short jumps.


#10
zklhp2012-09-02 22:02
AX=0000  BX=0000  CX=FDFC  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0B76  ES=0B76  SS=0B86  CS=0B86  IP=0003   NV UP EI PL NZ NA PO NC
0B86:0003 E9EDFD        JMP     FDF3
-t
此时我要跳到FDF3 而现在IP是3+3=6 所以我要给IP加上FD ED 从机器码看正好是这个数
AX=0000  BX=0000  CX=FDFC  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0B76  ES=0B76  SS=0B86  CS=0B86  IP=FDF3   NV UP EI PL NZ NA PO NC
0B86:FDF3 40            INC     AX

AX=0001  BX=0000  CX=FDFC  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0B76  ES=0B76  SS=0B86  CS=0B86  IP=FDF4   NV UP EI PL NZ NA PO NC
0B86:FDF4 E90F02        JMP     0006
-t
现在IP是FDF7 要到06得加一个数让它溢出 于是我加了020F 溢出后是06
AX=0001  BX=0000  CX=FDFC  DX=0000  SP=0000  BP=0000  SI=0000  DI=0000
DS=0B76  ES=0B76  SS=0B86  CS=0B86  IP=0006   NV UP EI PL NZ NA PO NC
0B86:0006 B8004C        MOV     AX,4C00

看来书上说的是错的 而且指令手册也没说这回事

不过又说回来了 这个特性是编译器的么 是所有编译器都有还是只有masm有 呵呵 你们研究研究罢

好问题 有意思 加高亮了

#11
zklhp2012-09-02 22:04
楼主很细心啊 以后肯定是大牛 希望你为祖国多做贡献 加油哦
#12
有容就大2012-09-02 22:14
膜拜高亮
#13
admin_xyz2012-09-02 22:29
难怪叫jmp near。。。
#14
admin_xyz2012-09-02 22:31
还为祖国做贡献。。。我都高三了才这水平。。。丢死人了
#15
zklhp2012-09-02 22:43
我高三的时候不琢磨这么细

不过研究这个跟高考没关系 要好好学习 祝楼主早日金榜题名
#16
pangding2012-09-02 23:31
此帖彰显了 zklhp 的钻研精神。值得大家学习。
#17
信箱有效2012-09-02 23:48
送快递这么久,从来没钻研过什么东西。倒是经常把快件划几道,看看里面是神马。
#18
heliang62912012-09-02 23:56
我来告诉你吧,这个关键在于
这句代码的长度并未超过near类型的长度,虽然你这里定义的字节数超过了。
实际上,你混淆了 指令语句 与 数据的区别。
这里的jmp是jmp 中间的代码,实际上,这里定义的字节空间是在其他段中,而你的代码是在cs段中,所以能编译。
相反,如果,你在jmp后面加上这么多数量的nop,你就跳转不过去啦。
明白了吗?
#19
heliang62912012-09-02 23:57
晕,写了这么多,才发现已经 结贴了。。。。。
我晕。。。。
#20
pangding2012-09-03 00:21
是吗,jmp 如果跳不过去会有什么表现?出段错误吗?

我的这个代码,在我的电脑上是能运行的:
程序代码:
.text
        .global  _start

_start:
    xorl    %eax, %eax
    jmp     s
    .rept   65000
    nop
    .endr
s:
    incl     %eax

    xorl    %ebx, %ebx
    movl    $1, %eax
    int     $0x80



[ 本帖最后由 pangding 于 2012-9-3 00:22 编辑 ]
#21
有容就大2012-09-03 14:10
回复 18楼 heliang6291
你这个说法可能也不对
我去做了个实验
一般来讲 jmp short s 的ip 修改范围是 -128~127
那么这个程序
程序代码:
;#Mode=DOS
;
MASMPlus 单文件代码模板 - 纯 DOS 程序
;
--------------------------------------------------------------------
;
单个文件需要指定编译模式,否则默认是EXE方式,在系统设置中可以设置默认是DOS还是Windows.
;
编译模式自带了DOS/COM/CON/EXE/DLL/LIB这几种,如果有必要,可以更改ide.ini添加新的编译模式
;
当然,更好的是创建为一个工程.更方便及易于管理,使用方法:按Ctrl多选->创建工程.必须有多个文件

assume cs:code
code segment
start:  jmp short s
        db 128 dup (0)
        s : mov ax, 0ffffh
        mov        ax, 4c00h
        int        21h
code ends
end start
是跳不过去的 因为128大于127
编译器提示 :error A2075: jump destination too far : by 1 byte(s)
而jmp near ptr s的ip修改范围是(书上说)-32768~32767
但是
程序代码:
;#Mode=DOS
;
MASMPlus 单文件代码模板 - 纯 DOS 程序
;
--------------------------------------------------------------------
;
单个文件需要指定编译模式,否则默认是EXE方式,在系统设置中可以设置默认是DOS还是Windows.
;
编译模式自带了DOS/COM/CON/EXE/DLL/LIB这几种,如果有必要,可以更改ide.ini添加新的编译模式
;
当然,更好的是创建为一个工程.更方便及易于管理,使用方法:按Ctrl多选->创建工程.必须有多个文件

assume cs:code
code segment
start:  jmp near ptr s
        db 65525 dup (0)
        s : mov ax, 0ffffh
        mov        ax, 4c00h
        int        21h
code ends
end start
是能通过编译的 如果把65525加一后即65526那么编译通不过
提示:error A2103: segment exceeds 64K limit : code
可见和nop没多大关系啊 貌似short很老实的遵循规则 而near ptr 就有点不守规矩了 不知什么原因
#22
有容就大2012-09-03 14:13
貌似db ??? dup (0)里究竟放多少个字节和一个段(segment)的长度上限有关系
#23
pangding2012-09-03 16:26
回复 22楼 有容就大
这些限制是 dos 这个系统的限制,还是 x86 架构的限制?
#24
有容就大2012-09-03 16:59
回复 23楼 pangding
是在MASMPlus里编译的 ;#Mode=DOS模式
#25
zklhp2012-09-03 17:49
以下是引用pangding在2012-9-3 16:26:12的发言:

这些限制是 dos 这个系统的限制,还是 x86 架构的限制?

段的大小有上限 是架构的限制罢
#26
pangding2012-09-03 21:23
以下是引用zklhp在2012-9-3 17:49:12的发言:


段的大小有上限 是架构的限制罢

我刚查 x86 的手册,段描述符里描述段长度的 limit 字段有 20位,所以段长度的上限至少应该有 1M。
如果开了分页,粒度位 G 置 1,则段的长度是页的整数倍,段长度的上限就会变成 4K * 1M = 4G。
#27
有容就大2012-09-03 21:56
回复 26楼 pangding
可能程序是局限在16位下的吧
#28
admin_xyz2012-09-03 22:11
回复 18楼 heliang6291
dup定义的不在code段里?

[ 本帖最后由 admin_xyz 于 2012-9-3 22:14 编辑 ]
1