unconditional direct jump not permitted in 64 bit?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
unconditional direct jump not permitted in 64 bit?
(my previous problems with jumps were errors in my code)
My laptop fails on a "jmp" instruction in Nasm 64 (simply ignores it although it compiles and links). Googling, I found a lot of confusing info: "there is no such instruction" and some indirect way to do this although it is 32 bit examples.
The manual makes reference to "rip" but if this needs to be part of the instruction, I have no idea how to do it.
I have seen this 32 bit code that's supposed to do the trick (in 32 bits):
Code:
call next_line
next_line:
pop eax
Can someone tell me if a "jmp label" instruction should work if "label:" previously exists (in which case the error is likely to be in the code).
(my previous problems with jumps were errors in my code)
My laptop fails on a "jmp" instruction in Nasm 64 (simply ignores it although it compiles and links).
I found a lot of confusing info: "there is no such instruction"
That is because you almost never need a direct jmp. You almost always use a relative jmp. In asm a relative jmp and a direct jmp may look the same. In modes where both are possible, the assembler must choose which is appropriate.
Quote:
Can someone tell me if a "jmp label" instruction should work if "label:" previously exists
The assembler is multi-pass so the label will be understood whether it is earlier in the source code or later.
"jmp label" will be a relative (rather than direct) jmp whenever the label is in the same link time segment as the jmp instruction.
What kind of jmp is required may be more complicated when the destination is in a different link time segment. The assembler plus the linker and/or loader might do some tricky things so a relative jmp still works, or you might have a problem.
I am reluctant to put the listing of the assembly code as it is 267 lines long and I suspect my mistake is probably very obvious as described below. However I will do so if absolutely necessary.
It looks like my code is not laid out correctly. This is the result of "strace".
"Got there OK." and "Found byte 0" and "Res..." are messages described below (I only have a short need for assembly and no time to learn how to use the debugger.)
The code is laid out as follows:
Code:
section .text
global _start
_start: ; ELF entry point
%include "open_read" ; OK
some working code here - checked every line of it
%include "exit" ; must be first
;These are subroutines
%include "convert"
%include "bindec"
%include "errors"
;
section .data
%include "messages"
%include "definitions"
I think the "error" block (%include "errors") or the "messages" block (%include "messages") or both is the problem as I laid them one after the other in a way that is not compatible for the assembler but I can't figure out and I cant find what the correct way of doing it is. The blocks are as follows:
Code:
error000:
mov rax, 1 ; sys_write
mov rdi, 1 ; STDOUT
mov rsi, message000 ; buffer
mov rdx, [message000L] ; length of buffer
syscall
; This was tested with and without the exit code below because this exit code does not have a "ret" which I thought did not matter.
mov rax, 60 ; sys_exit
xor rdi, rdi ; 0
syscall
error001:
mov rax, 1 ; sys_write
mov rdi, 1 ; STDOUT
mov rsi, message001 ; buffer
mov rdx, [message001L] ; length of buffer
syscall
call exit
This is repeated a number of times.
Code:
message000: db 'Got there OK.', 10
message000L: db 14
message001: db 'Found byte 0', 10
message001L: db 12
write(1, "Got there OK.\n\16Found byte 0\n\fRes"..., 7070761840551085582) = -1 EFAULT (Bad address)
...
error000:
mov rsi, message000 ; buffer
mov rdx, [message000L] ; length of buffer
...
message000: db 'Got there OK.', 10
message000L: db 14
I believe mov rdx, [message000L] would read 8 bytes starting from the location labeled message000L, but db 14 only 14 into a single byte, the following 7 bytes are whatever happen to be there. That's why the length parameter is wrong in the write syscall. You should use dq to make an 8 byte length (alternatively, change the code to read a single byte).
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.