Imagine I want to jump using an immediate (hidden behind a macro):
jmp label
How do I specify the width of the immediate so for example the jmp instruction for rel8 is executed. I tried:
jmp byte label
But it doesn't work. I'm working with the MSVC inline assembler.
The assembler will automatically choose the smallest encoding for the jump instruction. With MASM you can override this with jmp SHORT label, but the Microsoft inline assembler ignores the SHORT keyword.
Note that even with MASM, when using the SHORT keyword the label has to be defined somewhere else in the assembly file and be within –128 to +127 bytes of the jump instruction. Otherwise you'll get an error.
Related
I tried to assemble a file with NASM, but it pointed to this line in the file:
mov al, byte ptr es:[bx]
saying:
error: comma, colon or end of line expected
I found a page on this site saying that NASM doesn't like the word "ptr" and it would be happy if I wrote:
mov al, byte es:[bx]
instead. So I took out the word "ptr" and NASM is still not happy. Here is what NASM gives me when I leave out the word "ptr":
warning: register size specification ignored
and:
error: invalid combination of opcode and operands
It's a catch 22! NASM is angry whether or not I put in the word "ptr". Can anybody help me with this?
I got it!
NASM is happy if I write:
mov al,byte [es:bx]
like Guy Sirton said. If I leave out the word "byte" from the instruction, here is what would happen. If the instruction is one like this:
mov al, [es:bx]
where NASM can see that I want to move one byte, since I'm storing it in al, it won't complain. But, if the instruction is one like this:
mov [es:bx],0xff
where NASM can't see how much memory I want to store 0xff in, it will give you such an error:
error: operation size not specified
It's important to know, especially if you are using this tutorial, that NASM won't except the regular way.
I am debugging a Linux program to which I have no symbols. The binary is stripped. No big deal, I can handle that. However, how can I skip a call inside the debugger when I reach a particular piece of code?
What I am asking is not this: Use gdb to debug assembly, how to skip a call
I am interested if I have a:
call 0x12345678
...
to jump to the ... straight without executing the call.
How can I do that?
After some more reading I found the solution.
In my case I know the opcode for the call is fives bytes long, so I can resolve it by setting the GDB register name $pc ("program counter") to jump over it:
set $pc+=5
According to the comment on this answer by Employed Russian the following provides the same functionality:
jump *$pc+5
Assuming you have the call at address 0x01234567 and want to skip five bytes, you can do the following in your .gdbinit:
b *0x01234567
commands 1
x/i $pc
echo Not executing the call\n
set $pc+=5
x/i $pc
end
Set the rip value to the address of the instruction right after this call 0x12345678.
Ive been from tasm from a while and now migrating to nasm. One thing I notice is that given this code
mov ah,00h
int 16h
cmp ah,3Bh
je aaaa
jne bbbb
why is that if i compiled and link and run it in nasm, it doesnt produce a window like a command prompt that waits for my keyboard input (it just finishes executes by closing it)? before, this code works well in tasm and when i run it, it opens a prompt and then waits my keyboard entry.
(One thing I notice in tasm is that int 21h function 01,02,09 seems to work well but here in nasm, it doesnt). Thanks
Thanks
JMP $ LOOPS THE WINDOW INDEFFENITELY,
THIS IS BAD.
INSTEAD DETECT KEYPRESS FOR ENTER,
ADD A CONDITION LIKE A WHILE LOOP TO DETERMINE IF TO GO TO IT YOU CAN DETECT KEY PRESS TO BREAK THE CONDITION
In Visual C's __asm, I'd like to do a jump to a location that's stored in a register, but it doesn't seem to work for conditional jumps, e.g. JAE. Ordinarily this works fine (if you use a label).
lea ecx, 0x0000001f[edx]
;jmp ecx ;ok
;jae EXIT_LOOP ;ok
jae ecx ; not ok "improper operand type"
Is there any way to do a jae with a register (or stack) variable with Visual C __asm? Maybe there's a different way to approach this problem (conditionally jump somewhere using a number, not label, known at compile time)?
Perhaps that's because there is no such opcode on the x86: you can't use a conditional jump except to a label. You probably want to:
...
jb skip
jmp ecx
skip:...
[Editing to add the label-less version]
This is ugly and sort of defeats one goal of using ASM (namely performance): note that JB (jump below) is equivalent to JC (jump on carry). Let A be the address to jump to if AE and B be the address if B:
...
sbb eax,eax,0 // propagate carry flag into register; eax == 0 or -1
and eax,B-A // eax = 0 or B-A
add eax,A // eax = A or B
jmp eax
You still need to figure out the addresses of where you want to go...
More involved tricks if you want to use other flags. You need to use the lahf or pushf instructions to get the flags into a processable position.
Ugh.
I've written a simple bootloader in Assembly (NASM syntax), however when I run it in QEMU, the newlines show up like this:
This is my code:
Is there a way to stop 0Ah from pushing the lines forward?
.loop_top:
mov si, text_string ; Put string position into SI
call print_string ; Call our string-printing routine
loop .loop_top
jmp $ ; Jump here - infinite loop!
text_string db "This is my cool new OS!", 0Ah, 0
Well, obviously :-) your "print_string" subroutine takes the 0x0a seriously -- it's called "LF", and it does just that, advances to the next line.
My guess is that using 0x0a 0x0d will do the trick.
I believe that sending a \r will make the cursor return to the left side of the screen. So, you should use \r\n or something similar to make new lines.
I'm not sure without more details. I'm not for sure how your print_string procedure is implemented. If implemented by BIOS calls, such as by cycling through the string using int 0x10, AH=0x0E, then the above solution will work, or you can do something like using int 0x10, AH=0x03 to adjust the cursor position manually.