linux下能否用intel汇编,linux 汇编学习之hello world(intel和at&t)

在 Linux 操作系统中,你有很多办法可以实现在屏幕上显示一个字符串,但最简洁的方式是使用 Linux 内核提供的系统调用。使用这种方法最大的好处是可以直接和操作系统的内核进行通讯,不需要链接诸如 libc 这样的函数库,也不需要使用 ELF 解释器,因而代码尺寸小且执行速度快。

我们分别使用nasm和gas两种汇编器来编译我们的程序,这样我们可以看到Intel和AT&T两种语法格式了。

使用的工具

当然首先我们需要汇编编译器nasm和gas。然后我们需要链接器-ld,因为汇编编译器是生成的只是object代码。

Linux是一个32位的,运行在保护模式下的操作系统,使用的是flat memory 模式,使用ELF格式的二进制代码。

一个程序可以划分为下面几个部分: .text,.data,.bss。.text是一些只读的代码,.data是可读可写的数据区,.bss则是可读可写的没有初始化的数据区。当然可以有其他一些标准的部分,也可以使用户自己定义的sections,但是我们这里不关心。一个程序至少有.text部分。

下面就是我们的第一个程序“hello,world”。我们给出两个版本,分别是nasm和gas两种。

NASM (hello.asm)

--------------

; hello.asm

section .data            ; 数据段声明

msg db "Hello, world!", 0xA     ; 要输出的字符串

len equ $ - msg                 ; 字串长度

section .text            ; 代码段声明

global _start            ; 指定入口函数

_start:                  ; 在屏幕上显示一个字符串

mov edx, len     ; 参数三:字符串长度

mov ecx, msg     ; 参数二:要显示的字符串

mov ebx, 1       ; 参数一:文件描述符(stdout)

mov eax, 4       ; 系统调用号(sys_write)

int 0x80         ; 调用内核功能

; 退出程序

mov ebx, 0       ; 参数一:退出代码

mov eax, 1       ; 系统调用号(sys_exit)

int 0x80         ; 调用内核功能

对于nasm,下面的语法:

$ nasm -f elf hello.asm

然后我们就要使用这个object文件来生成可执行代码。这里使用链接器链接:

$ ld -s -o hello hello.o

这样我们就获得了我们的可以执行的代码“hello,world”。

AT&T 格式

#hello.s

.data                    # 数据段声明

msg : .string "Hello, world!\\n" # 要输出的字符串

len = . - msg                   # 字串长度

.text                    # 代码段声明

.global _start           # 指定入口函数

_start:                  # 在屏幕上显示一个字符串

movl $len, %edx  # 参数三:字符串长度

movl $msg, %ecx  # 参数二:要显示的字符串

movl $1, %ebx    # 参数一:文件描述符(stdout)

movl $4, %eax    # 系统调用号(sys_write)

int  $0x80       # 调用内核功能

# 退出程序

movl $0,%ebx     # 参数一:退出代码

movl $1,%eax     # 系统调用号(sys_exit)

int  $0x80       # 调用内核功能

编译命令一样:(假设汇编源文件名为:hello.s)

$ as hello.s -o hello.o

$ ld hello.o -o hello

附录:

linux2.6.28内核源码:

sys_write

376 asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_    t count)

377 {

378         struct file *file;

379         ssize_t ret = -EBADF;

380         int fput_needed;

381

382         file = fget_light(fd, &fput_needed);

383         if (file) {

384                 loff_t pos = file_pos_read(file);

385                 ret = vfs_write(file, buf, count, &pos);

386                 file_pos_write(file, pos);

387                 fput_light(file, fput_needed);

388         }

389

390         return ret;

391 }

sys_exit

1146 asmlinkage long sys_exit(int error_code)

1147 {

1148         do_exit((error_code&0xff)<<8);

1149 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值