手撕编译原理:汇编语言不会编

用户头像
贾献华
关注
发布于: 2020 年 06 月 03 日

NASM



Installation of NASM



wget -c http://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.xz
tar -xf nasm-2.14.02.tar.xz
cd nasm-2.14.02
ls
./configure --prefix=/usr && make
sudo make install



version



$ nasm -v
NASM version 2.14.02 compiled on Jun 1 2020



demo



global main
main:
mov eax, 5
ret



Makefile



SRCS := first.asm
OBJS := $(SRCS:.asm=.o)
TARGET := $(OBJS:.o=)
all: $(TARGET)
$(TARGET): $(OBJS)
gcc -m32 $< -o $@
%.o: %.asm
nasm -f elf $< -o $@
.PHONY: all clean
clean:
-rm -rf $(TARGET) $(OBJS)



make



$ make
gcc -m32 first.o -o first
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/usr/bin/ld: cannot find /lib/libgcc_s.so.1
collect2: error: ld returned 1 exit status
make: *** [Makefile:7: first] Error 1



glibc-devel



sudo yum install glibc-devel.i686 -y
sudo yum install libgcc.i686 -y



make



nasm -f elf first.asm -o first.o
gcc -m32 first.o -o first



查看返回值



# ./first ; echo $?
./first
echo $?



运算



add.asm



global main
main:
mov eax, 15
mov ebx, 19
add eax, ebx
ret



gdb



$ gdb add
(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
0x08048480 <+0>: mov eax,0xf
0x08048485 <+5>: mov ebx,0x13
0x0804848a <+10>: add eax,ebx
0x0804848c <+12>: ret
0x0804848d <+13>: xchg ax,ax
0x0804848f <+15>: nop
End of assembler dump.
(gdb) b *0x08048485# break *0x08048485
(gdb) r # run
(gdb) i r eax # info registers eax
eax 0xf 15
(gdb) si # stepi Step one instruction exactly.
(gdb) info registers ebx
ebx 0x13 19
...
(gdb) i r # info registers
eax 0x22 34
ecx 0xbddbc2e 199081006
edx 0xffffd514 -10988
ebx 0x13 19
esp 0xffffd4ec 0xffffd4ec
ebp 0x0 0x0
esi 0xf7fc0000 -134479872
edi 0x0 0
eip 0x804848c 0x804848c <main+12>
eflags 0x216 [ PF AF IF ]
cs 0x23 35
ss 0x2b 43
ds 0x2b 43
es 0x2b 43
fs 0x0 0
gs 0x63 99
...
(gdb) c # continue
Continuing.
[Inferior 1 (process 21718) exited with code 042]
(bdb) q



跳转



cmp & jmp



后缀 | 意义

---|---

a | above

e | equal

b | below

n | not

g | greater

l | lower

s | signed

z | zero



标志寄存器 `eflags`



eip : CPU 接下来要执行的代码



循环



for, while, do-while ==> goto + if



  • goto: jmp

  • if: cmp & jmp



函数



  • call + ret



  • 保存现场

  • 传递参数

  • 返回



x86 的环境下,栈是朝着低地址的方向伸长的。



  • 栈: call 指令保存 eip

  • esp(stack pointer): 寄存器



  • 汇编中发生函数调用相关的指令call和ret

  • call指令会产生跳转动作,与jmp不同的是,call之后可以通过ret指令跳回来

call和ret的配合是依靠保存eip的值到栈里,返回时恢复eip实现的

esp记录着当前栈顶所在的位置,每次call和ret执行都会伴随着入栈和出栈,也就是esp会发生变化



递归



  • push + pop



函数调用相关指令



  1. 通过寄存器传递参数和返回值

  2. 函数调用后的返回地址会保存到堆栈中

  3. 函数的局部状态也可以保存到堆栈中



明天手撕《汇编语言》第3版。



参考:



  1. https://www.nasm.us/

  2. http://www.linuxfromscratch.org/blfs/view/svn/general/nasm.html

  3. https://zhuanlan.zhihu.com/c_144694924



用户头像

贾献华

关注

及时当勉励 岁月不待人 2018.06.04 加入

https://2020.iosdevlog.com

评论

发布
暂无评论
手撕编译原理:汇编语言不会编