flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
Tomasz Grysztar 19 Mar 2007, 21:06
lazer1 wrote: (A) and (B) are totally different jumps, As long as your ORG reflects correctly the address at which the code is loaded, they both jump to the same address, that is stored in memory cell at GS:16h - however you also have to specify the size of this address and whether it is near or far jump, what cannot be deduced from your sample. |
|||
![]() |
|
lazer1 19 Mar 2007, 21:54
Tomasz Grysztar wrote:
ok, I had been in fact using it as eg "jmp [ gs : xyz.abc ]" where I had: Code: struc xyz { .x dq 0 .y dq 0 .abc dq 0 } virtual at 0 xyz xyz end virtual .... mov rax, 0 jmp [ gs : rax + xyz.abc ] so fasm was getting the size indirectly from the struc, you say I should use ORG, there is a problem, I cannot use ORG because I have relocated the code. the address stored at absolute address "[ gs : rax + xyz.abc ]" is the place I want to jmp to. so Code: mov rax,0 jmp [ gs : rax + xyz.abc ] is what I want to do, however I need *all* registers, *none* are free, rip-relative doesnt help as I want to jump to an absolute address which isnt known at compile time and there are no free registers available also the code is not allowed to store the address in the body of the code as the code needs to be recursively reentrant, in the original code the ORG is correct, but the code is then relocated to somewhere completely different. The rip relative addressing still functions correctly as that is relocation invariant. gs contains a relocated pointer to the struc xyz, the only way I can see is to push the address on the stack and then do "ret" that would preserve all registers including rsp and rflags, however I was wondering if there was a way of doing it via modifying "jmp [ gs : xyz.abc ]" |
|||
![]() |
|
lazer1 19 Mar 2007, 22:03
can I do it like this maybe?:
Code: jmp [ gs : .next + xyz.abc ] .next: gs contains a relocated address and I want to jmp from the address stored at an offset of xyz.abc from gs, |
|||
![]() |
|
lazer1 19 Mar 2007, 23:06
lazer1 wrote: can I do it like this maybe?: this still fails, the following code fails: Code: ; THIS CODE IS RELOCATED, expressions like [ somelabel ] ; are ok after relocation, lea is needed to determine the ; relocated address, lea rax, [ .xyz ] ; read relocated address of .xyz to rax, mov [ .uvw ], rax ; set up the relocated address to jmp to lea rax, [ .uvw ] ; relocated address of .uvw to rax write_to_gs_macro rax ; write rax to gs via wrmsr mov rax, 0 ; set rax to 0 jmp near qword [ gs : .next + 0 ] ; supposed to jmp to .xyz .next: .abc: echo_bad ; macro to echo 'bad' .xyz: echo_good ; macro to echo 'good' .x: jmp .x .uvw dq 0 ; relocated address of .xyz to be stored here, if I run this the machine crashes, but if instead I do the same but replace the jmp instruction by "jmp near qword [ gs : rax + 0 ]" then it indeed echoes 'good' why is the initial code fragment failing? "jmp near qword [ gs : 0 ]" also crashes, tried it just now, Last edited by lazer1 on 19 Mar 2007, 23:19; edited 1 time in total |
|||
![]() |
|
Tomasz Grysztar 19 Mar 2007, 23:17
If your code changes position in a way that you really need to use absolute addressing, you can enforce 32-bit absolute addressing like this:
Code: jmp near qword [ gs : dword 0 ] But note that there is no absolute 64-bit mode addressing available (except for some of the MOV forms), so if you needed to use address not fitting in 32 bits, you'd have to use register anyway. The reference - section 2.1.19 of manual: fasm's manual wrote: The long mode uses also the instruction pointer based addresses, you can specify it manually with the special RIP register symbol, but such addressing is also automatically generated by flat assembler, since there is no 64-bit absolute addressing in long mode. You can still force the assembler to use the 32-bit absolute addressing by putting the dword size override for address inside the square brackets. There is also one exception, where the 64-bit absolute addressing is possible, it's the mov instruction with one of the operand being accumulator register, and second being the memory operand. To force the assembler to use the 64-bit absolute addressing there, use the qword size operator for address inside the square brackets. When no size operator is applied to address, assembler generates the optimal form automatically. |
|||
![]() |
|
lazer1 19 Mar 2007, 23:31
Tomasz Grysztar wrote: If your code changes position in a way that you really need to use absolute addressing, you can enforce 32-bit absolute addressing like this: SUCCESS! ![]() gs wont fit in 32 bits but the offset is some small value, probably not even 8 bit, in the above example just 0, gs is just an absolute relocated pointer to a struct the fragment you give does function the way I want, so that resolves the problem, the following quote is the explanation then, Quote:
|
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.