简体   繁体   English

简单程序的组装问题

[英]Assembly problem with simple program

I am trying to learn assembly from scratch.我正在尝试从头开始学习汇编。 I have been reading up quite a bit, but even the following simple program I found in a reference book has me stumped:我已经阅读了很多,但即使是我在参考书中找到的以下简单程序也让我难倒:

section .data
msg db "Hello!", 0xa
len equ $ - msg
section .text

     global _start

_start:


move edx, len
move ecx, msg
move ebx, 1
move eax, 4
int  0x80
move ebx, 0
move eax, 1
int 0x80

Now apparently this is supposed to print "Hello".现在显然这应该打印“你好”。 But I don't even know whats happening at any of the stages.但我什至不知道在任何阶段发生了什么。 The first two stages put the message length and messgae in two registers, which are never used again.前两个阶段将消息长度和消息放在两个寄存器中,不再使用。 I don't understand why.我不明白为什么。

I don't know why four different registers are needed.我不知道为什么需要四个不同的寄存器。

int 0x80 is a mechanism in some (a) UNIX-like operating systems for making system calls. int 0x80是某些(a)类 UNIX 操作系统中用于进行系统调用的机制。

For these calls, the registers are used for specific values.对于这些调用,寄存器用于特定值。 From the syscalls file:syscalls文件:

0 STD NOHIDE { int nosys(void); } syscall nosys_args int
1 STD NOHIDE { void exit(int rval); } exit rexit_args void
2 STD POSIX  { int fork(void); }
3 STD POSIX  { ssize_t read(int fd, void *buf, size_t nbyte); }
4 STD POSIX  { ssize_t write(int fd, const void *buf, size_t nbyte); }

you can see that number 4 is the write call and needs three other parameters.您可以看到数字 4 是write调用并且需要其他三个参数。 Number 1 is exit and needs only the return code.数字 1 是exit ,只需要返回代码。

When making the call, eax is the syscall that you're making while ebx , ecx and edx are the three parameters (assuming they're all needed - exit for example only needs one).进行调用时, eax是您正在进行的系统调用,而ebxecxedx是三个参数(假设它们都是必需的 - 例如exit只需要一个)。

So, you could comment the code as follows:因此,您可以按如下方式注释代码:

move edx, len   ; length of message (nbyte).
move ecx, msg   ; message to print (buf).
move ebx, 1     ; file descriptor 1 (stdout).
move eax, 4     ; write syscall.
int  0x80       ; do it.

move ebx, 0     ; exit code (rval).
move eax, 1     ; exit syscall.
int 0x80        ; do it.

(a) Later versions of Linux introduced a new interface which can use different methods based on which provides the best speed. (a)更高版本的 Linux 引入了一个新界面,该界面可以使用不同的方法来提供最佳速度。 For example, some Intel chips are much faster if you use sysenter rather than int 0x80 .例如,如果您使用sysenter而不是int 0x80 ,某些英特尔芯片会快得多。

IIRC the int 0x80 instruction is used to invoke a syscall by using the interrupt vector. IIRC int 0x80指令用于通过使用中断向量来调用系统调用。 In your example the values in ebx and eax are used to specify which syscall you are gonna call (probably the print operation on stdout).在您的示例中, ebxeax中的值用于指定您要调用的系统调用(可能是 stdout 上的打印操作)。

The syscall knows by convenction that edx and ecx should contain what is gonna be printed.系统调用通过约定知道edxecx应该包含将要打印的内容。

On many systems, int 80h is the system call gate.在许多系统上, int 80h系统调用门。 The syscall number is in eax .系统调用号在eax ebx , ecx and edx contain additional parameters: ebxecxedx包含附加参数:

move edx, len
move ecx, msg
move ebx, 1    ; fd 1 is stdout
move eax, 4    ; syscall 4 is write
int  0x80      ; write(1, msg, len)
move ebx, 0
move eax, 1    ; syscall 1 is exit
int 0x80       ; exit(0)

When you call a system call, the 'int' mnemonic, a system interruption is generated.当您调用系统调用时,“int”助记符会产生系统中断。 It kinda "jumps" to a system function, which, in this case, prints output (depends on eax).它有点“跳转”到系统函数,在这种情况下,它打印输出(取决于 eax)。

This interruption uses all those registers to know what to do.此中断使用所有这些寄存器来知道要做什么。 The interrupt reads eax, check what function you want and uses the other registers to do so.中断读取 eax,检查您想要的功能并使用其他寄存器来执行此操作。

eax is the function number, 4 means sys_write, which writes a string to a stream/file descriptor. eax 是函数编号,4 表示 sys_write,它将字符串写入流/文件描述符。

Now it knows you want to write something to some place, then it uses the other registers to those informations.现在它知道你想写一些东西到某个地方,然后它使用其他寄存器来处理这些信息。

for eax = 4 and int 0x80 this is the meaning for the other registers:对于 eax = 4 和 int 0x80,这是其他寄存器的含义:

ebx = output (1 = stdout) ebx = 输出(1 = 标准输出)
ecx = address of the string ecx = 字符串地址
edx = length of the string edx = 字符串的长度

You can read this:你可以阅读这个:

http://www.intel.com/Assets/ja_JP/PDF/manual/253665.pdf http://www.intel.com/Assets/ja_JP/PDF/manual/253665.pdf

Section 6.4 It has some stuff about Interruptins and Exceptions.第 6.4 节有一些关于中断和异常的内容。

And you can start writing Intel 80x86 assembly code, which is simpler and easier to understand, here are some links:并且可以开始编写Intel 80x86汇编代码,比较简单易懂,这里有一些链接:

Mnemonics/Code tables cheatsheet: http://www.jegerlehner.ch/intel/助记符/代码表备忘单: http : //www.jegerlehner.ch/intel/

Some introduction sites: http://mysite.du.edu/~etuttle/math/8086.htm http://www.malware.org/teaching/assembly.htm一些介绍网站: http : //mysite.du.edu/~etuttle/math/8086.htm http://www.malware.org/teaching/assembly.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM