I'm trying to learn a bit of assembly over here, and I need a bit of help from the 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 immediately segfaults. I made test.working.s by using the disassembly window in eclipse and just writing a small C program to print something using printf.
So, questions!
Why does
test.s
not workIn my C program, main is defined as main(int argc, char ** argv) is it not? Hence shouldn't I need to
pop
twice at the start if I don't need those arguments?In x86-64, I read somewhere that %rax was the 64-bit register, %eax was the 32 bit register, and %ax was the 16 bit register. So does the register look like this:
XX XX EE EE RR RR RR RR
(R = 4bits of RAX, E = 4 bits of EAX, X = 4 bits of AX) on a little-endian system (1 is represented as 0x01000000, I think...)?GCC wont let me type
pop %eax
orpush %eax
. It will only let me type the 64 bit versions or the 16 bit versions. How do I push the 32 EAX bits of RAX to the stack then? How do I pop just 32 bits?test.working.s (I imagine this is answered in 1, but if not...) calls printf by changing registers, NOT by pushing stuff onto the stack. I presume this is because it is faster? How do you know when to do this and in what order when calling c functions?
Will this also work on Windows x86-64? I understand that the operation of printf may be different, but if I clean up and restore the registers after the printf, I should be OK right?
How are you supposed to clean up and restore the registers? According to http://www.cs.uaf.edu/2005/fall/cs301/support/x86/, it says that I "must save %esp, %ebp, %esi, %edi". Is that referring to the fact that, when I write a function, these registers must come back out the way they came in, or that I should save them myself before I call a function. It's probably the former, since %esp, but just checking!
It's pretty clear that I won't be needing x86-64, especially since I'm just starting, so how do I alter compile.sh for just x86?
Does
.asciz
simply mean.ascii
+"\0"
?I can return large structs (>64bit) that reside on the stack in C. How is this achieved in assembly?
Cheers for any help!