A Minimal Application in Assembly:不要迷信洋人
2010-04-02 22:32
204 查看
在PC Ubuntu下,我用汇编能写的最小应用程序为:
.text
.globl _start
__start:
mov $1, %eax /* __NR_exit, see /usr/include/asm/unistd_32.h */
mov $0, %ebx /* exit status */
int $0x80 /* _exit */
用gcc编译后生成的程序是600字节。
$ gcc -O3 -nostdlib min.s -o min
$ wc -c min
600 min
当然,这个min程序一无用处,运行时什么都没作,直接退出。退出的状态0,返回给其父进程。
$ ./min;echo $?
0
但就是这样一个应用,老外也能玩出花样,http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
上介绍如何把可执行程序压榨到45字节。Gee! 这种本来应该是日本人拿手的,怎么白人也喜欢小的?
另外,Jeff Duntemann在其“Assembly Language Step by Step Programming with Linux"一书 Page 242声称:
The _start label indicates where the program begins. Every Linux assembly language program has to be marked this way, and with the precise label _start. (It’s case sensitive, so don’t try using _START or _Start.) Furthermore, this label must be marked as global at the top of the .text section, as shown. This is a requirement of the Linux operating system. Every executable program for Linux has to have a label _start in it somewhere, irrespective of the language it’s written in: C, Pascal, assembly, no matter.
这说法是有问题的。我来说两句:
1。 The _start label indicates where the program begins
OK,基本正确,但是不是100%。参照我后面从GNU拷贝过来的linker说明。
2。Every Linux assembly language program has to be marked this way, and
with the precise label _start. (It’s case sensitive, so don’t try using
_START or _Start.)
Wrong。参照我后面从GNU拷贝过来的linker说明。
3。 This is a requirement of the Linux operating system
Wrong。是linker要根据_start符号来决定程序的执行入口点,然后写到可执行文件的ELF header中。kernel根据ELF header找到entry point,kernel根本不不要知道_start。
4。Every Linux assembly language program has to be marked this way, and with the precise label _start.
Wrong。参照我后面从GNU拷贝过来的linker说明。
GNU linker文档对程序的执行入口点有如下说明:
3.4.1 Setting the entry point
The first instruction to execute in a program is called the entry point
. You can use the
linker script command to set the entry point. The argument is a symbol name:
There are several ways to set the entry point. The linker will set the entry point by trying each of the following methods in order, and stopping when one of them succeeds:
the `-e'
entry
command-line option;
the
command in a linker script;
the value of the symbol
, if defined;
the address of the first byte of the `.text'
section, if present;
The address
.
我们代码验证上述第一种情况,用begin代替_start。
$ cat begin.s
.text
.globl begin
begin:
mov $1, %eax /* syscall no, see /usr/include/asm/unistd_32.h */
mov $0, %ebx /* exit status */
int $0x80 /* _exit */
$ gcc -nostdlib -Wl,-entry=begin begin.s -o begin
$ ./begin;echo $?
0
果然没有任何问题。
结论:我们不要迷信洋人的书。
.text
.globl _start
__start:
mov $1, %eax /* __NR_exit, see /usr/include/asm/unistd_32.h */
mov $0, %ebx /* exit status */
int $0x80 /* _exit */
用gcc编译后生成的程序是600字节。
$ gcc -O3 -nostdlib min.s -o min
$ wc -c min
600 min
当然,这个min程序一无用处,运行时什么都没作,直接退出。退出的状态0,返回给其父进程。
$ ./min;echo $?
0
但就是这样一个应用,老外也能玩出花样,http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
上介绍如何把可执行程序压榨到45字节。Gee! 这种本来应该是日本人拿手的,怎么白人也喜欢小的?
另外,Jeff Duntemann在其“Assembly Language Step by Step Programming with Linux"一书 Page 242声称:
The _start label indicates where the program begins. Every Linux assembly language program has to be marked this way, and with the precise label _start. (It’s case sensitive, so don’t try using _START or _Start.) Furthermore, this label must be marked as global at the top of the .text section, as shown. This is a requirement of the Linux operating system. Every executable program for Linux has to have a label _start in it somewhere, irrespective of the language it’s written in: C, Pascal, assembly, no matter.
这说法是有问题的。我来说两句:
1。 The _start label indicates where the program begins
OK,基本正确,但是不是100%。参照我后面从GNU拷贝过来的linker说明。
2。Every Linux assembly language program has to be marked this way, and
with the precise label _start. (It’s case sensitive, so don’t try using
_START or _Start.)
Wrong。参照我后面从GNU拷贝过来的linker说明。
3。 This is a requirement of the Linux operating system
Wrong。是linker要根据_start符号来决定程序的执行入口点,然后写到可执行文件的ELF header中。kernel根据ELF header找到entry point,kernel根本不不要知道_start。
4。Every Linux assembly language program has to be marked this way, and with the precise label _start.
Wrong。参照我后面从GNU拷贝过来的linker说明。
GNU linker文档对程序的执行入口点有如下说明:
3.4.1 Setting the entry point
The first instruction to execute in a program is called the entry point
. You can use the
ENTRY
linker script command to set the entry point. The argument is a symbol name:
ENTRY(symbol ) |
the `-e'
entry
command-line option;
the
ENTRY(symbol )
command in a linker script;
the value of the symbol
start
, if defined;
the address of the first byte of the `.text'
section, if present;
The address
0
.
我们代码验证上述第一种情况,用begin代替_start。
$ cat begin.s
.text
.globl begin
begin:
mov $1, %eax /* syscall no, see /usr/include/asm/unistd_32.h */
mov $0, %ebx /* exit status */
int $0x80 /* _exit */
$ gcc -nostdlib -Wl,-entry=begin begin.s -o begin
$ ./begin;echo $?
0
果然没有任何问题。
结论:我们不要迷信洋人的书。
相关文章推荐
- WPF部署问题 解决:The application requires that the assembly...be installed in the GAC
- .net core An assembly specified in the application dependencied mainfest<****.json>was not found解决办法
- Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)
- Debugging Data Bindings in a WPF or Silverlight Application
- Using Assembly Language in Linux
- 严重: Servlet [login_fali] in web application [/StudyforJSP] threw load() exception javax.servl
- Inline Assembly(for GNU assembler)-the difference of AT&T & intel
- Linux C中内联汇编的语法格式及使用方法(Inline Assembly in Linux C)
- sbt公布assembly解决jar包冲突 deduplicate: different file contents found in the following
- java.lang.RuntimeException: Method setUp in android.test.ApplicationTestCase not mocked. See http://g.co/androidstudio/not-mocked for details.
- 解决 VMware 虚拟机 中被提示 “请不要在虚拟机中运行此程序”或者“Themida Sorry, this application cannot run under a Virtual Mac
- Resource Planning Application in SAP CRM
- Counting Number Down In Console Application
- 报错:An error occurred at line: 22 in the generated java file The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory
- C#解决类似System.Data.SQLite.SQLiteParameter' is defined in an assembly that is not referenced. You must
- 在Android程序里显示等待滚动圈(使用ProgressDialog)| Show waiting rolling circle in android application (using ProgressDialog)
- [BEROR]CodeSign error: code signing is required for product type 'Application' in SDK 'iOS 8.1'
- Using GET_APPLICATION_PROPERTY in Oracle D2k Forms
- 虚拟机提示the virtual machine is in use by an application on your host computer的解决方案
- There was an internal api err.. & The entitlements specified in your application’s Code Signing...