2015-07-12 71 views
0

這個問題是不是關於LEA指令,不是關於它是如何工作的,它不是重複的。這是關於OPCODE代這個指令。LEA指令操作碼生成

LEA操作碼中的操作數是多少?

這裏是我的 「你好world.fasm」:

彙編程序

format ELF64 executable at 0000000100000000h ; put image over 32-bit limit 

segment readable executable 

entry $ 

    mov edx,msg_size ; CPU zero extends 32-bit operation to 64-bit 
       ; we can use less bytes than in case mov rdx,... 
    lea rsi,[msg] 
    mov edi,1  ; STDOUT 
    mov eax,1  ; sys_write 
    syscall 

    xor edi,edi  ; exit code 0 
    mov eax,60  ; sys_exit 
    syscall 

segment readable writeable 


msg db 'Hello 64-bit world!',0xA 

msg_size = $-msg 

十六進制轉儲

000000b0 ba 14 00 00 00 48 8d 35 15 10 00 00 bf 01 00 00 |.....H.5........| 
000000c0 00 b8 01 00 00 00 0f 05 31 ff b8 3c 00 00 00 0f |........1..<....| 
000000d0 05 48 65 6c 6c 6f 20 36 34 2d 62 69 74 20 77 6f |.Hello 64-bit wo| 
000000e0 72 6c 64 21 0a         |rld!.| 
000000e5 

正如你所看到的,指令興趣lea rsi, [msg]具有操作碼:48 8d 35 15 10 00 00。從CPU指令參考我可以看出,48是64位前綴的排序,8dLEA代碼,35是目標寄存器rsi參考,而15 10 00 00是... ???它是什麼?

0x1521的十進制數,我可以用一個手指跟蹤十六進制轉儲,即「Hello world」消息正好是LEA rsi, [msg]指令後的21個字節。所以它必須是一個相對地址,但10 00 00來自哪裏?我會理解,如果它是1500 00,但由於某種原因它是1500 00

不幸的是,CPU引用並不是非常有用,它們非常正式,我無法與它們相處。他們是這樣的:

8D r LEA Gvqp M gen datamov Load Effective Address 

所以,請解釋LEA操作碼是如何在這種情況下產生的,如果可能的話一般英寸

回答

3

我要回答你關於15 10 00 00是什麼的問題,而不是關於LEA如何編碼的其他問題。

讓我們對可執行文件的一些信息與readelf

 

$ readelf -l leatest 

Program headers: 
    Type   Offset    VirtAddr   PhysAddr   FileSiz   MemSiz    Flg Align 
    LOAD   0x00000000000000b0 0x00000001000000b0 0x00000001000000b0 0x0000000000000021 0x0000000000000021 R E 1000 
    LOAD   0x00000000000000d1 0x00000001000010d1 0x00000001000010d1 0x0000000000000014 0x0000000000000014 RW  1000 

然後讓我們拆解的二進制,ndisasm(從NASM):

ndisasm -b 64 leatest 

000000B0 BA14000000  mov edx,0x14 
000000B5 488D3515100000 lea rsi,[rel 0x10d1] 
000000BC BF01000000  mov edi,0x1 
000000C1 B801000000  mov eax,0x1 
000000C6 0F05    loadall286 
000000C8 31FF    xor edi,edi 
000000CA B83C000000  mov eax,0x3c 
000000CF 0F05    loadall286 
000000D1 48    rex.w  ; <-- The string starts here 
000000D2 656C    gs insb 
000000D4 6C    insb 
000000D5 6F    outsd 
000000D6 2036    and [rsi],dh 
000000D8 342D    xor al,0x2d 
000000DA 62    db 0x62 
000000DB 697420776F726C64 imul esi,[rax+0x77],dword 0x646c726f 
000000E3 210A    and [rdx],ecx 

所以你的第二個部分 - 其中字符串位於 - 具有虛擬地址0x00000001000010d1,而代碼從虛擬地址0x00000001000000b0開始。這些段在4096字節的邊界(0x1000)上對齊,所以該字符串位於0x10D1 - 0xBC相對於使用is的指令(等於0x1015)。因此,你看到在hexdump中看到15 10 00 00的原因,因爲這是相對偏移0x00001015

+0

這是否意味着整個二進制文件'hello'被加載到所有(兩個)段中?我的意思是*整個*文件,而不僅僅是段的數據'phoff-phoff + phsize'。 – exebook

+0

如果你的意思是它將如何被操作系統加載,那麼我不確定。我還沒有處理ELF可執行文件的這些細節。 – Michael