In MASM, the following two pieces of code do exactly the same thing, but only the second one assembles. Why?
mov eax,[403000]
jmp 4010FF
mov ebx,403000
mov eax,[ebx]
mov edx,4010FF
jmp edx
If I remember correctly you don't have that JMP opcode available in win32 so you move the value into a register and jump to that address.
Lousy masm? :toothy
:bg
Victor,
I am not sure anything else can use that opcode either, if all else fails,
push 12345678
ret
AeroASM,
INTEL CPUs use a jump instruction that is controlled by an offset RELATIVE to the EIP. Therefore, you need to specify a label so MASM knows how to calculate the offset. If you code JMP 12345, the question is 12345 from what? If you code JMP BEGIN+12345, where BEGIN coulld be a label at the beginning of the code segment, then MASM has a reference to calculate. There is no immediate absolute jump instruction for the INTEL CPU. MASM has no way of checking a jump specified by a register, so anything goes in that case. Ratch
roticv,
QuoteLousy masm?
Can't blame MASM because INTEL does not have a immediate absolute jump instruction. Ratch
I mean lousy masm in recongnising the address and encode the jmp properly.
roticv,
QuoteI mean lousy masm in recongnising the address and encode the jmp properly.
Masm can't encode it because there is no immediate absolute jump instruction. MASM has to work with what is avaibable. And an absolute address cannot be converted into a relative address unless a relative point of reference like a label is known. Ratch
I know that there is no absolute jmp. My point is that masm is unable to think of the address as relative and encode it as a relative jmp.
roticv,
QuoteI know that there is no absolute jmp. My point is that masm is unable to think of the address as relative and encode it as a relative jmp.
Sure it can. Simply code JMP $+12345 , and it will code a jump relative from the current location of the EIP. Ratch
There is an absolute jump, with the EA opcode.
That's far jmp if I remember correctly.
AeroASM,
QuoteThere is an absolute jump, with the EA opcode.
What is 'EA'? Please define the acronym upon first usage. Also please post a coding example of a absolute jump. Ratch
roticv,
QuoteThat's far jmp if I remember correctly.
No way! It stays within the code segment. Ratch
EA as in 0EAh, is the hex opcode for an absolute jump. Like this:
db 66h,67h
db 0EAh
dd 12345678h
dw 08h
;equals jmp 08h:12345678h
I spent several hours trying to encode a JMP rel32 to an absolute address with a macro, and I could not make it work. But if you know the address of the destination and the address of the next instruction, it's easy enough to calculate the displacement as the address of destination minus the address of next instruction.
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.486 ; create 32 bit code
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\kernel32.lib
include \masm32\macros\macros.asm
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
.data
.code
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
db 0E9h
;dd 401040h-401005h
dd OFFSET there - ($+4)
back:
print chr$("back")
mov eax,input(13,10,"Press enter to exit...")
exit
there:
print chr$("there and ")
jmp back
; ««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start
QuoteI spent several hours trying to encode a JMP rel32 to an absolute address with a macro, and I could not make it work.
What exactly is not working, Michael?
Hi MazeGen,
When I try to calculate the displacement directly, MASM returns:
"error A2094: operand must be relocatable"
Every method I have tried resulted in this error, some other error, or an incorrect displacement value.
jmpabs MACRO absaddr
LOCAL label
db 0E9h
; displacement = absaddr - label
; or
; displacement = absaddr - ($+4)
dd absaddr - label
dd absaddr - ($+4)
label:
ENDM
The strange thing is that MASM will accept any of these:
absaddr + label
absaddr + ($+4)
label - absaddr
($+4) - absaddr
But the calculated displacement is not correct, and I can find no method of manipulating the calculated result to a correct value that will not at some point return this or another error.
AeroASM ,
OP code 0EAH is for intersegment jumps. INTEL documentation gives the coding as JMP ptr16:32, which is a 6 byte immediate address. MASM seems to want to convert this coding into a 4 byte relative address, which is shorter and executes quicker. Since the flat model has only one code segment, seems to me that JMP rel32 covers everything. Ratch
In theory, I guess you could patch the executable to use a constant value there, but there's no telling where it would jump to.
Quote from: MichaelW on March 21, 2005, 11:26:14 AM
Every method I have tried resulted in this error, some other error, or an incorrect displacement value.
jmpabs MACRO absaddr
LOCAL label
db 0E9h
; displacement = absaddr - label
; or
; displacement = absaddr - ($+4)
dd absaddr - label
dd absaddr - ($+4)
label:
ENDM
I don't think the linker object files support subtracting a label value. The assembler can subtract a label from another label if they are in the same file (or included into the same file) and in the same segment.