gcc - Noob ASM Questions -
i'm trying learn bit of assembly on here, , need bit of pros!
test.s:
.data helloworld: .asciz "printf test! %i\n" .text .globl main main: push $0x40 push $helloworld call printf mov $0, %eax ret
test.working.s:
.data helloworld: .asciz "printf test! %i\n" .text .globl main main: mov $0x40, %esi mov $printf_test, %edi mov $0x0, %eax call printf mov $0, %eax ret
compile.sh:
rm test gcc test.s -o test -lc chmod 777 test ./test
test.s segfaults. made test.working.s using disassembly window in eclipse , writing small c program print using printf.
so, questions!
why
test.s
not workin c program, main defined main(int argc, char ** argv) not? hence shouldn't need
pop
twice @ start if don't need arguments?in x86-64, read somewhere %rax 64-bit register, %eax 32 bit register, , %ax 16 bit register. register this:
xx xx ee ee rr rr rr rr
(r = 4bits of rax, e = 4 bits of eax, x = 4 bits of ax) on little-endian system (1 represented 0x01000000, think...)?gcc wont let me type
pop %eax
orpush %eax
. let me type 64 bit versions or 16 bit versions. how push 32 eax bits of rax stack then? how pop 32 bits?test.working.s (i imagine answered in 1, if not...) calls printf changing registers, not pushing stuff onto stack. presume because faster? how know when , in order when calling c functions?
will work on windows x86-64? understand operation of printf may different, if clean , restore registers after printf, should ok right?
how supposed clean , restore registers? according http://www.cs.uaf.edu/2005/fall/cs301/support/x86/, says "must save %esp, %ebp, %esi, %edi". referring fact that, when write function, these registers must come out way came in, or should save them myself before call function. it's former, since %esp, checking!
it's pretty clear won't needing x86-64, since i'm starting, how alter compile.sh x86?
does
.asciz
mean.ascii
+"\0"
?i can return large structs (>64bit) reside on stack in c. how achieved in assembly?
cheers help!
because in 64-bit mode should passing arguments in registers rather on stack (see this answer). if wasn't case, don't have size specifier
push $0x40
, it's quite you're pushing 16-bit value rather 32 bits.the top of stack contain return address wherever call
main
came (e.g.__libc_start_main
). below you'll findargc
,argv
. there's no need pop of (you shouldn't pop of them since need preserve return address).the 32-bit value 1 written 0x00000001 (most significant nybble left), , stored
(low address) 01 00 00 00 (high address)
in little-endian configuration. since it's typical write numbers significant digits first rather according how they're stored, make sense writerax
descriptionrr rr rr rr ee ee xx xx
, possibly bit index markers if it's unclear order is.again, that's calling convention 64-bit x86 code, described in this answer.
not without changes, since 64-bit calling convention used windows is different (the registers used passing arguments
rcx, rdx, r8, r9
).by saving them on stack example. there callee saved registers , caller saved registers.
the callee (the function being called) must save registers , restore them before returning in order comply calling convention. 64-bit program on linux-type systemrbx, rbp, r12-r15
(on 64-bit windows includesrsi
,rdi
).
caller (the code calling function) must consider registers volatile (i.e. can changed function) , should save , restore them if needs values after function returns. on linux-type system theserax, rcx, rdx, rsi, rdi, r8-r11
.the gnu assembler should support
-m32
command-line option specify you're assembling 32-bit code.yes.
Comments
Post a Comment