我们如何按照这些说明使用组装中的跳转?

时间:2018-10-18 03:06:03

标签: assembly x86 machine-code

我知道,装配跳线基本上是从一个位置转到另一个位置。

说我们有

804828f: 74 05            je XXXXXXX
8048291: e8 1e 00 00 00 call 80482b4 

根据这本书,我真正要做的就是在8048291上添加0x05,这将产生8048291,但是我对这里的命令感到困惑。根据这本书,操作数je是je,等于/ 0

然后我们遇到了一个复杂的问题,我真的很难缠住我的头。

8048357: 72 e7                        jb XXXXXXXX
8048359: c6 05 10 a0 04 08 01 movb $0x1,0x804a010

据此,由于e7是-25的1位带符号表示, jb转到地址8048340。

那。 。 。对我毫无意义。 。 。完全没有。例如,如果某项已签名并且1字节的最大值不应该只是2?其次,如果值为-25,为什么原点是8048340?如果不涉及19个,我们如何从59增至40?

我认为答案是:

我在脑子里想了一秒钟,但是要从十六进制25中得到19,我应该将16除以25,抓住它的余数9,然后加9到10,在这种情况下1代表什么?

老实说,我迷失了一个带符号的单字节值。

2 个答案:

答案 0 :(得分:2)

在某种意义上说,可以根据需要的顺序排列代码块,因此汇编中的分支是灵活的。您也可以通过跳转到同一块来合并分支。要对此存档,说明必须能够向前和向后跳转。以下示例显示了向后跳转的用法。

073000:  bf 08 00 00 00          mov    edi, 0x8
073005:  31 c0                   xor    eax, eax
073007 <loop>:
073007:  01 f8                   add    eax, edi
073009:  83 ef 01                sub    edi, 0x1
07300c:  75 f9                   jne    073007 <loop>
07300e:

向前跳操作码后的数字为正;向后跳操作码后的数字为负。在二进制世界中,数字的符号由其最高位决定。在示例中,十六进制f9是二进制11111001,其含义为-7(有关转换方法,请参见下文)。由于hex(07300e)-7是hex(073007),如果未设置,它将跳到073007是ZF(这意味着上例中的edi在减去后不为零)。

在我看来,您对十六进制数字感到困惑。我将使用一些示例来说明如何将它们转换为十进制数字。 Google,您可以找到更多详细信息。

Unsigned numbers:
0x1234 =  1*16^3 +  2*16^2 + 3*16^1 +  4 = 4660 
0x3420 =  3*16^3 +  4*16^2 + 2*16^1 +  0 = 13344 
0x0A0B =  0*16^3 + 10*16^2 + 0*16^1 + 11 = 2571   (A is 10; B is 11)
0x8000 =  8*16^3 +  0*16^2 + 0*16^1 +  0 = 37268
0xFF7A = 15*16^3 + 15*16^2 + 7*16^1 + 10 = 65402  (F is 15)

Signed numbers:
0x1234 =   ; positive because 1 is smaller than 8
0x3420 =   ; positive because 3 is smaller than 8 
0x0A0B =   ; positive because 0 is smaller than 8
0x8000 =   ; negative because 8 is NOT smaller than 8
0xFF7A =   ; negative because F (15) is NOT smaller than 8

Signed numbers:
0x1234 = 4460  ; positive numbers are calculated like unsigned number
0x3420 = 13344 ; positive numbers are calculated like unsigned number
0x0A0B = 2571  ; positive numbers are calculated like unsigned number
0x8000 = 32768 - 65536 = -32768 ; a simple way to calculate negative number
0xFF7A = 65402 - 65536 = -134 ; a simple way to calculate negative number

当第一位数字> = 8时,最高位为1,因此数字为负。

65536是2 ^ 16。

答案 1 :(得分:0)

0x05 + 0x80482910x8048296。您似乎添加了零,而不是5。这是有条件地在5个字节的call上跳转(em),如果设置了ZF,则会进行跳转。 (http://felixcloutier.com/x86/Jcc.html)。

x86分支位移相对于分支指令的末尾,即下一条指令的开始。

即使反汇编输出中的地址不是以0x开头,地址也以十六进制而不是十进制表示。请注意,804828f包含f作为数字。位移为1字节而不是1位,因此范围为-128至+127。如果rel8超出范围,则rel32跳转的编码会有所不同。