32bit cpuid as+ld 32bit hello nasm+ld 32bit hello gcc+ld
64bit cpuid as+ld 64bit hello as+ld 64bit hello nasm+ld
调用号文件: /usr/include/asm/unistd_32.h /usr/include/asm/unistd_64.h
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
假设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
源文件为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
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
[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汇编器
调用约定 wikipedia:https://en.wikipedia.org/wiki/Calling_conventioncdel, gcc, ia-32(i386)
例子: 主调函数 功能函数 3种方式去make: @1: obj: as, elf: ld, 不需要动态库的情况,比较好的解决方案 + as --32 -gstabs mymath.s -o obj/mymath.o + as --32 -gstabs myfun.s -o obj/myfun.o + ld -emain -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 obj/myfun.o obj/mymath.o -o myfun.bin -lc @2:obj: gcc -m32, elf: ld. 需要把汇编功能函数编译成共享库的解决方案 + gcc -m32 -fPIC -c mymath.s -o obj/mymath.o + gcc -m32 -shared obj/mymath.o -o obj/libmymath.so + gcc -m32 -c myfun.s -o obj/myfun.o + ld -emain -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 obj/myfun.o -o myfun.bin -lc -L obj/ -lmymath @3: obj: gcc -m32, elf: gcc -m32,这个阶段有警告,目前不知道原因 + gcc -m32 -fPIC -c mymath.s -o obj/mymath.o + gcc -m32 -fPIC -c myfun.s -o obj/myfun.o + gcc -m32 -fPIC obj/myfun.o obj/mymath.o -o bin/myfun.elf /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: obj/myfun.o: warning: relocation in readonly section `.text' /usr/lib/gcc/x86_64-pc-linux-gnu/7.3.0/../../../../x86_64-pc-linux-gnu/bin/ld: warning: creating a DT_TEXTREL in a shared object.
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
下一条指令
nexti
print multiple registers
(gdb) print {$eax,$ebx,$ecx} $8 = {0, 350, 24420}
常用参数
[-D|--disassemble-all] [-j section|--section=section] [-r|--reloc] // 在看CSAPP的(链接) 章节的时候要看Elf32_Rel.type
db, dw, dd, dq 1 2 4 8 bytes
nteger types .octa 16 bytes on x86_64 and x86 .quad 8 bytes on x86_64 and x86 .long and .int 4 bytes on x86_64 and x86 .word, .short and .hword 2 bytes on x86_64 and x86 .byte is, of course, 1 byte on x86_64 and x86 Floating-point types .tfloat 10 bytes on x86_64 and x86 .double 8 bytes on x86_64 and x86 .single and .float 4 bytes on x86_64 and x86
后缀含义 https://www3.nd.edu/~dthain/courses/cse40243/fall2015/intel-intro.html Suffix Name Size B BYTE 1 byte (8 bits) W WORD 2 bytes (16 bits) L LONG 4 bytes (32 bits) Q QUADWORD 8 bytes (64 bits) https://www3.nd.edu/~dthain/courses/cse40243/fall2015/intel-intro.html
http://web.mit.edu/gnu/doc/html/as_7.html .lcomm symbol , length Reserve length (an absolute expression) bytes for a local common denoted by symbol. The section and value of symbol are those of the new local common. The addresses are allocated in the bss section, so that at run-time the bytes start off zeroed. Symbol is not declared global (see section .global symbol, .globl symbol), so is normally not visible to ld. The syntax for .lcomm differs slightly on the HPPA. The syntax is `symbol .lcomm, length'; symbol is optional.
http://web.mit.edu/gnu/doc/html/as_7.html#SEC97 .comm symbol , length .comm declares a named common area in the bss section. Normally ld reserves memory addresses for it during linking, so no partial program defines the location of the symbol. Use .comm to tell ld that it must be at least length bytes long. ld allocates space for each .comm symbol that is at least as long as the longest .comm request in any of the partial programs linked. length is an absolute expression. The syntax for .comm differs slightly on the HPPA. The syntax is `symbol .comm, length'; symbol is optional.
.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
.comm name, size, alignment alignment is optional
64位hello world
Quick review, nasm的db dw dd DB - Define Byte. 8 bits DW - Define Word. Generally 2 bytes on a typical x86 32-bit system DD - Define double word. Generally 4 bytes on a typical x86 32-bit system
32bit系统浮点数:通过栈传参 C代码, gcc -S 手工打造的汇编代码
as: eatMsg: .ascii "abc\n" 得到标号地址: movl $eatMsg, %ecx # ecx= addr of msg 桔标号处存的数: movl eatMsg, %ecx # ecx = value: 0xa636261 nasm: eatMsg: db "abc",10 标号地址: mov ecx, eatMsg mov ecx, [eatMsg] gdb: p/x &eatMsg : addr of label p/x eatMsg: value in label addr
https://stackoverflow.com/questions/64187905/gas-aarch64-syntax-to-get-ascii-string-length