可执行文件中的.text段大于.text节.为什么



我在NASM中有以下"uppercaser.asm"汇编程序,它将用户输入的所有小写字母转换为大写字母:

section .bss
Buff resb 1
section .data
section .text
global _start
_start:
nop            ; This no-op keeps the debugger happy
Read:   mov eax,3      ; Specify sys_read call
mov ebx,0      ; Specify File Descriptor 0: Standard Input
mov ecx,Buff   ; Pass offset of the buffer to read to
mov edx,1      ; Tell sys_read to read one char from stdin
int 80h        ; Call sys_read
cmp eax,0       ; Look at sys_read's return value in EAX
je Exit         ; Jump If Equal to 0 (0 means EOF) to Exit
; or fall through to test for lowercase
cmp byte [Buff],61h  ; Test input char against lowercase 'a'
jb Write        ; If below 'a' in ASCII chart, not lowercase
cmp byte [Buff],7Ah  ; Test input char against lowercase 'z'
ja Write        ; If above 'z' in ASCII chart, not lowercase
; At this point, we have a lowercase character
sub byte [Buff],20h  ; Subtract 20h from lowercase to give uppercase...
; ...and then write out the char to stdout
Write:  mov eax,4       ; Specify sys_write call
mov ebx,1       ; Specify File Descriptor 1: Standard output
mov ecx,Buff    ; Pass address of the character to write
mov edx,1       ; Pass number of chars to write
int 80h         ; Call sys_write...
jmp Read        ; ...then go to the beginning to get another character
Exit:   mov eax,1       ; Code for Exit Syscall
mov ebx,0       ; Return a code of zero to Linux
int 80H         ; Make kernel call to exit program

然后,该程序与调试器的-g -F stabs选项组装在一起,并链接到ubuntu 18.04中的32位可执行文件。

对段运行readelf --segments uppercaser,对节运行readelf -S uppercaser,我看到文本段和文本节的大小不同。

readelf --segments uppercaser

Elf file type is EXEC (Executable file)
Entry point 0x8048080
There are 2 program headers, starting at offset 52
Program Headers:
Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
LOAD           0x000000 0x08048000 0x08048000 0x000db 0x000db R E 0x1000
LOAD           0x0000dc 0x080490dc 0x080490dc 0x00000 0x00004 RW  0x1000
Section to Segment mapping:
Segment Sections...
00     .text
01     .bss

readelf -S uppercaser

Section Headers:
[Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
[ 0]                   NULL            00000000 000000 000000 00      0   0  0
[ 1] .text             PROGBITS        08048080 000080 00005b 00  AX  0   0 16
[ 2] .bss              NOBITS          080490dc 0000dc 000004 00  WA  0   0  4
[ 3] .stab             PROGBITS        00000000 0000dc 000120 0c      4   0  4
[ 4] .stabstr          STRTAB          00000000 0001fc 000011 00      0   0  1
[ 5] .comment          PROGBITS        00000000 00020d 00001f 00      0   0  1
[ 6] .shstrtab         STRTAB          00000000 00022c 00003e 00      0   0  1
[ 7] .symtab           SYMTAB          00000000 0003d4 0000f0 10      8  11  4
[ 8] .strtab           STRTAB          00000000 0004c4 000045 00      0   0  1

在节描述中,可以看到.text节的大小是5Bh=91字节(与size命令得到的数字相同(,而在段描述中,我们看到大小是0x000DB,相差128字节。为什么?

来自Elf32_Phdr(程序头(结构的精灵手册页面:

p_filesz此成员保存的文件映像中的字节数片段。它可能是零。

p_memsz此成员保存内存映像中的字节数分段的。它可能是零。

这种差异在某种程度上与.bss部分有关吗?

请注意,文件地址0处的第一个程序段从虚拟地址0x08048000开始,而不是从与.text部分对应的VA0x08048080开始。

事实上,readelf显示为00 .text的段包括ELF文件头(52字节(、对齐、两个程序头(2*32字节(和.text部分的netto内容,所有这些都从文件地址0映射到VA0x08048000

最新更新