扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
二、求最大值的GNU汇编代码max.s
我们提供的服务有:成都网站建设、成都做网站、微信公众号开发、网站优化、网站认证、蓝田ssl等。为上1000家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的蓝田网站制作公司
#开头的为注释,下同
#数据段
.section .data
data_items:
.long 'H','E','L','L','O','_','W','O','R','L','D','!','!',0#使用long类型是为了看大端和小端
#代码段
.section .text
#将入口地址声明为全局可见,默认是局部可见
.globl _start
_start:
#GNU汇编中左边是源操作数,右边是目标操作数,与intel汇编正好相反
#常数要加$,不加$的符号视为地址,寄存器前面要加%
movl $0, %edi
movl data_items(,%edi,4), %eax # (data_items+ 4*edi) → eax
#将data_items的第一个数据放入寄存器ebx中,ebx保存最大值
movl %eax, %ebx# eax → ebx
start_loop:
#数据为0时结束,表示没有数据了
cmpl $0, %eax
je loop_exit
incl %edi
movl data_items(,%edi,4), %eax# (data_items+ 4*edi) → eax
cmpl %ebx, %eax
jle start_loop# eax = ebx
movl %eax, %ebx# eax ebx,赋给eax → ebx
jmp start_loop
loop_exit:
movl $1, %eax# 1号系统调用,exit(ebx),结束进程
int $0x80
三、编译和运行
环境:ubuntu 15.04
编译:gcc -c -o max.o max.s
链接:ld -o max max.o
运行./max
运行之后通过echo $?可以查看该命令的退出状态,该状态即为最大值,95。
gcc中有指示编译成32位的选项-m32,此时代码段和数据段的对齐就不会是0x200000,距离会变得比较短。对应ld要加-m elf_i386选项,指明为32位平台。
ld中有指示代码段的加载地址的选项-Ttext,如-Ttext 0,则加载地址为0
四、EXE文件的格式
4.1 查看max的ELF等定位信息
命令:readelf -a max
-a表示查看所有ELF信息
可以得到如下的输出信息:
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 #EXE文件的魔数
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)#是EXE文件
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4000b0 #程序入口地址,虚拟地址
Start of program headers: 64 (bytes into file)#文件中program headers 的偏移
Start of section headers: 656 (bytes into file)#文件中section headers的偏移
Flags: 0x0
Size of this header: 64 (bytes)#ELF header的大小
Size of program headers: 56 (bytes)#program headers的大小
Number of program headers: 2 #program headers的个数
Size of section headers: 64 (bytes) #section headers的大小
Number of section headers: 6#section headers的个数
Section header string table index: 3
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
#代码段入口地址0x4000b0,文件偏移地址0xb0,大小为0x2d
[ 1] .text PROGBITS 00000000004000b0 000000b0
000000000000002d 0000000000000000 AX 0 0 1
#数据段入口地址0x6000dd,文件偏移地址0xdd,大小为0x38
[ 2] .data PROGBITS 00000000006000dd 000000dd
0000000000000038 0000000000000000 WA 0 0 1
#节名表入口地址0x0,文件偏移地址0x115,大小为0x27
[ 3] .shstrtab STRTAB 0000000000000000 00000115
0000000000000027 0000000000000000 0 0 1
#符号表入口地址0x0,文件偏移地址0x140,大小为0x108
[ 4] .symtab SYMTAB 0000000000000000 00000140
0000000000000108 0000000000000018 5 7 8
#字符串表入口地址0x0,文件偏移地址0x248,大小为0x48
[ 5] .strtab STRTAB 0000000000000000 00000248
0000000000000048 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
#program headers 提供段定位信息
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
#代码段,读和可执行,虚拟地址0x400000 →物理地址0x400000,文件偏移0,
#长度为#0xdd,对齐为0x200000
#包含ELF header和代码段
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000000dd 0x00000000000000dd R E 200000
#数据段,读和写,虚拟地址0x6000dd →物理地址0x6000dd,文件偏移0xdd,长度为#0x38,对齐为0x200000
LOAD 0x00000000000000dd 0x00000000006000dd 0x00000000006000dd
0x0000000000000038 0x0000000000000038 RW 200000
Section to Segment mapping:
Segment Sections...
00 .text
01 .data
There is no dynamic section in this file.
There are no relocations in this file.
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
#符号表:程序中的符号及其对应的地址
Symbol table '.symtab' contains 11 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000004000b0 0 SECTION LOCAL DEFAULT 1
2: 00000000006000dd 0 SECTION LOCAL DEFAULT 2
3: 0000000000000000 0 FILE LOCAL DEFAULT ABS max.o
4: 00000000006000dd 0 NOTYPE LOCAL DEFAULT 2 data_items
5: 00000000004000bf 0 NOTYPE LOCAL DEFAULT 1 start_loop
6: 00000000004000d6 0 NOTYPE LOCAL DEFAULT 1 loop_exit
7: 00000000004000b0 0 NOTYPE GLOBAL DEFAULT 1 _start
8: 0000000000600115 0 NOTYPE GLOBAL DEFAULT 2 __bss_start
9: 0000000000600115 0 NOTYPE GLOBAL DEFAULT 2 _edata
10: 0000000000600118 0 NOTYPE GLOBAL DEFAULT 2 _end
No version information found in this file.
test.txt文件内容:
9
11
35
21
42
118
求最大值:
awk 'BEGIN {max = 0} {if ($1+0 max+0) max=$1} END {print "Max=", max}' test.txt
Max= 118
求最小值:
awk 'BEGIN {min = 65536} {if ($1+0 min+0) min=$1} END {print "Min=", min}' test.txt
Min= 9
求和:
cat test.txt|awk '{sum+=$1} END {print "Sum= ", sum}'
Sum= 236
求平均值:
cat test.txt|awk '{sum+=$1} END {print "Avg= ", sum/NR}'
Avg= 39.3333
读取10个数字存入数组中
然后使用一个变量max将它的初始值设置为数组中第一个元素的值
接着从数组中第二个元素开始遍历整个数组
如果某个元素的值大于max则将max设置为该值
如此遍历完整个数组后max中便是整个数组中最大的值
下面是一个简单的示例代码
#!/bin/bash
echo -n '输入10个数:'
read -a a
max=${a[0]};
for i in {1..9}
do
if [ ${a[$i]} $max ]
then
max=${a[$i]}
fi
done
echo "最大值为: $max"
exit 0
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流