Reputation: 9036
I am using YASM on Linux x86_64.
I am following an introduction to assembly language on the internet. I've covered basic data types. Now I'm diving into loops contruction. Good, but my first attempt is a failure. This code segfault around the use of the cmd
instruction:
segment .data
a dd 0x01,0x02,0x03,0x04
b dd 0x03,0x03,0x03,0x03
product dd 0x00
segment .text
global _start
_start:
mov rax,0
begin_while:
cmp rax,4
jnl end_while
inc rax
jmp begin_while
end_while:
mov rax,1
xor rbx,rbx
int 0x80
But when I add those few lines just after the _start
label, then it behaves as expected. i.e. no segfault.
push rbp
mov rbp,rsp
sub rsp,16
The book I am reading uses this construct from time to time. Not everytime. I understand that is has to do with the procedure to follow when calling a function. I guess it might be related to the libc runtime. Anyway, I do not understand why it's needed. So far with all the few simple programs I wrote (not so much) I never had to use it. Just today, now that I am using jmp
.
Does someone have a good explanation about it?
Upvotes: 1
Views: 317
Reputation: 84579
Well, you are using the x86
interrupt call
int 0x80
which should be changed to
syscall
for x86_64
. You are relying on x86
compatibility while using 64-bit
registers. As pointed out by Jester, your code will compile and run without error on x86_64
. (I have confirmed it both ways without error on AMD64 Linux) However, the extent to which this is true for all platforms is unclear.
In writing x86_64 code, should also change:
mov rax,1
to
mov rax, 0x3c ; 60 decimal
to setup the proper x86_64
exit syscall instead of relying on x86
compatibility. (in x86_64, the syscall number 1
is __NR_write 1
, see: /usr/include/asm/unistd_64.h
compared to /usr/include/asm/unistd_32.h
)
Upvotes: 1