有一个程序读取两个数字,将它们相加并打印结果:
SYS_EXIT equ 1
SYS_READ equ 3
SYS_WRITE equ 4
STDIN equ 0
STDOUT equ 1
section .text
global _start
_start:
mov edx, len1
mov ecx, msg1
mov ebx, STDOUT
mov eax, SYS_WRITE
int 0x80
mov ecx, numX
mov edx, 2
mov ebx, STDIN
mov eax, SYS_READ
int 0x80
mov edx, len2
mov ecx, msg2
mov ebx, STDOUT
mov eax, SYS_WRITE
int 0x80
mov ecx, numY
mov edx, 2
mov ebx, STDIN
mov eax, SYS_READ
int 0x80
mov eax, [numX]
sub eax, '0'
mov ebx, [numY]
sub ebx, '0'
add eax, ebx
add eax, '0'
mov [res], eax
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, res
mov edx, 2
int 0x80
mov eax, SYS_WRITE
mov ebx, STDOUT
mov ecx, msg4
mov edx, len4
int 0x80
mov eax,SYS_EXIT
int 0x80
section .data
msg1 db 'X=',
len1 equ $-msg1
msg2 db 'Y=',
len2 equ $-msg2
msg3 db 'X+Y='
len3 equ $-msg3
msg4 db 0xA, 0xB
len4 equ 2
segment .bss
numX resb 2
numY resb 2
res resb 1
这是它显示的内容objdump -D
app: file format elf32-i386
Disassembly of section .text:
08049000 <.text>:
8049000: ba 02 00 00 00 mov $0x2,%edx
8049005: b9 00 a0 04 08 mov $0x804a000,%ecx
804900a: bb 01 00 00 00 mov $0x1,%ebx
804900f: b8 04 00 00 00 mov $0x4,%eax
8049014: cd 80 int $0x80
8049016: b9 0c a0 04 08 mov $0x804a00c,%ecx
804901b: ba 02 00 00 00 mov $0x2,%edx
8049020: bb 00 00 00 00 mov $0x0,%ebx
8049025: b8 03 00 00 00 mov $0x3,%eax
804902a: cd 80 int $0x80
804902c: ba 02 00 00 00 mov $0x2,%edx
8049031: b9 02 a0 04 08 mov $0x804a002,%ecx
8049036: bb 01 00 00 00 mov $0x1,%ebx
804903b: b8 04 00 00 00 mov $0x4,%eax
8049040: cd 80 int $0x80
8049042: b9 0e a0 04 08 mov $0x804a00e,%ecx
8049047: ba 02 00 00 00 mov $0x2,%edx
804904c: bb 00 00 00 00 mov $0x0,%ebx
8049051: b8 03 00 00 00 mov $0x3,%eax
8049056: cd 80 int $0x80
8049058: a1 0c a0 04 08 mov 0x804a00c,%eax
804905d: 83 e8 30 sub $0x30,%eax
8049060: 8b 1d 0e a0 04 08 mov 0x804a00e,%ebx
8049066: 83 eb 30 sub $0x30,%ebx
8049069: 01 d8 add %ebx,%eax
804906b: 83 c0 30 add $0x30,%eax
804906e: a3 10 a0 04 08 mov %eax,0x804a010
8049073: b8 04 00 00 00 mov $0x4,%eax
8049078: bb 01 00 00 00 mov $0x1,%ebx
804907d: b9 10 a0 04 08 mov $0x804a010,%ecx
8049082: ba 01 00 00 00 mov $0x1,%edx
8049087: cd 80 int $0x80
8049089: b8 04 00 00 00 mov $0x4,%eax
804908e: bb 01 00 00 00 mov $0x1,%ebx
8049093: b9 08 a0 04 08 mov $0x804a008,%ecx
8049098: ba 02 00 00 00 mov $0x2,%edx
804909d: cd 80 int $0x80
804909f: b8 01 00 00 00 mov $0x1,%eax
80490a4: cd 80 int $0x80
Disassembly of section .data:
0804a000 <.data>:
804a000: 58 pop %eax
804a001: 3d 59 3d 58 2b cmp $0x2b583d59,%eax
804a006: 59 pop %ecx
804a007: 3d .byte 0x3d
804a008: 0a 0b or (%ebx),%cl
Disassembly of section .bss:
0804a00c <.bss>:
...
这是调试器显示的内容:
(gdb) run
Starting program: /home/rikitikitavi/projects/asm/app
X=5
Y=5
Breakpoint 1, 0x08049058 in ?? ()
(gdb) c
Continuing.
Breakpoint 2, 0x08049069 in ?? ()
(gdb) info registers
eax 0xa350a05 171248133
ecx 0x804a00e 134520846
edx 0x2 2
ebx 0xa05 2565
esp 0xffffd140 0xffffd140
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x8049069 0x8049069
eflags 0x206 [ PF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
(gdb) si
0x0804906b in ?? ()
(gdb) info registers
eax 0xa35140a 171250698
ecx 0x804a00e 134520846
edx 0x2 2
ebx 0xa05 2565
esp 0xffffd140 0xffffd140
ebp 0x0 0x0
esi 0x0 0
edi 0x0 0
eip 0x804906b 0x804906b
eflags 0x206 [ PF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x0 0
从objdump
地址可以看出0x08049069
,有一个加法命令—— add %ebx,%eax
。在执行此命令之前,寄存器中应该有必要的数字 5 和 5 eax
,ebx
相反,我分别看到了0xa350a05
和0xa05
。05
最后,可以说,暗示寄存器包含我需要的东西,但其余的呢?- 我理解正确,05
这是寄存器的内容,al
其余bl
的是垃圾?那么他是从哪里来的呢?
然后我将代码添加0
到结果中,将其写入内存并输出。如果您输入4
并且当您输入时,5
那么一切正常:
rikitikitavi@rikitikitavi:~/projects/asm$ ./app
X=4
Y=5
9
但如果你进入5
然后5
一切都打破了:
rikitikitavi@rikitikitavi:~/projects/asm$ ./app
X=5
Y=5
:
我什至理解它为什么会中断 - 因为第二个数字出现在十进制系统中并且添加代码0
并不完全正确(尽管结果,原则上,在 acsii 表:
之后立即是正确的)。9
我需要以某种方式将结果显示给我的朋友,但我不明白如何?
现在简短的问题:
- 为什么我在调试器中看到一些奇怪的寄存器值?
- 如何更改结果输出?
EAX
中(其中包含垃圾)。您必须在复制之前直接清除寄存器,或者使用如下指令进行复制movzx
:INT-29h
中,将 AL 输出到控制台 - 将其替换为 Linux 的适当输出。该程序是通用的,可以输出各种数字系统,从 BIN 及更高版本: