Linux下Asm汇编,链接,debug

生成64bit ELF

vim eatsyscall.asm

SECTION .data
EatMsg: db "Eat at Joe's!",10
EatLen: equ $-EatMsg
SECTION .bss
SECTION .text
global _start
_start:
		nop
		mov eax,4
		mov ebx,1
		mov ecx,EatMsg
		mov edx,EatLen
		int 80H
		mov eax,1
		mov ebx,0
		int 80H
unix>nasm -f elf64 -g -F stabs eatsyscall.asm
unix>ld -o eatsyscall eatsyscall.o
[dark@peak ch4AsmRight]$file eatsyscall
eatsyscall: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped

gcc生成32bit ELF

源文件为c语言,用gcc生成32bit ELF

假设makefile中有一个target叫p.

[ice@icefire ch7Link]$make p
gcc -Wall -g -O2 -c -m32 -o main.o main.c
gcc -Wall -g -O2 -c -m32 -o swap.o swap.c
gcc -Wall -g -O2 -m32 -o p main.o swap.o
[ice@icefire ch7Link]$file main.o
main.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
[ice@icefire ch7Link]$file swap.o
swap.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped
[ice@icefire ch7Link]$file p
p: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3033cdebf2b6130fa4aba2f5c640bbe67d6c1d81, not stripped
	

intel语法汇编,用nasm+ld

源文件为eatsyscall.asm

nasm -f elf32 -g -F stabs eatsyscall.asm
ld -m elf_i386 -o eatsyscall eatsyscall.o
[dark@peak ch4AsmRight]$file eatsyscall
eatsyscall: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
参考:ld生成32bit ELF

intel语法,用nasm+gcc

vim hello.asm

用gcc时候是入口是main而不是_start

	section .data
msg:
	db "hello,world",10
	len equ $-msg

	section .text
	global main
main:
	mov edx, len
	mov ecx, msg
	mov ebx,1
	mov eax,4 ;直接使用sys_write系统调用

	int 0x80
	mov ebx,0
	mov eax,1
	int 0x80
nasm -f elf -g -F stabs -o hello.o hello.asm
gcc -m32 -g -o hello hello.o
[dark@peak]$file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, not stripped

AT&T语法,GNU as+ld 实现32bit

[dark@peak ch3Sample]vim cpuid.s
.section .data
output:
	.ascii "The processor Vendor ID is ‘xxxxxxxxxxxx’\n"

.section .text
.global _start
_start:
	movl $0,	%eax
	cpuid
	movl $output, %edi

	movl %ebx,	28(%edi)
	movl %edx,	32(%edi)
	movl %ecx,	36(%edi)
#系统调用
	movl $4,	%eax
	movl $1,	%ebx
	movl $output,%ecx
	movl $42,	%edx
	int	$0x80
#系统调用结束,退出程序
	movl $1,	%eax
	movl $0,	%ebx
	int	$0x80
as --32 cpuid.s -o cpuid.o
ld -m elf_i386 -o cpuid cpuid.o
[dark@peak ch3Sample]$file cpuid
cpuid: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped

PS: as的注释风格GNU汇编器

在fedora24-x86_64中编译32bit汇编程序的小问题

1:没有/lib/ld-linux.so.2
dnf install glibc.i686
2:
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -lc signtest.o -o signtest
ld: cannot find -lc
对于libc这个动态库,名字必须要是libc.so,甚至连libc.so.6都是错误的
cd /lib/
ln -s libc-2.23.so libc.so

gdb debug Asm

参考blog:用gdb调试nasm汇编程序

下一条指令

nexti

some tips for gdb debug:

print multiple registers

(gdb) print {$eax,$ebx,$ecx}
$8 = {0, 350, 24420}

objdump使用

常用参数

[-D|--disassemble-all]
[-j section|--section=section]
[-r|--reloc] // 在看CSAPP的(链接) 章节的时候要看Elf32_Rel.type

GAS使用

gas中重复一块指令许多次

.rept count

Repeat the sequence of lines between the .rept directive and the next .endr directive count times.
For example, assembling

.rept   3
.long   0
.endr

is equivalent to assembling

.long   0
.long   0
.long   0

gas中.comm指令

.comm name, size, alignment
alignment is optional 

nasm汇编器相关

times伪指令,重复某一指令若干次

times prefix for nasm