x64 Intel Opcode 81 /2 - 64-bit

How does the processor differentiate between these two instructions?
81 /2 iw - Add with carry imm16 to r/m16.
81 /2 id - Add with carry imm32 to r/m32.
The only thing different I can see in the instruction is the size of the immediate value and that isn't enough, right? I mean if the immediate is two bytes an instruction could be right after it and the processor wouldn't know if it was 4 bytes of immediate or 2 bytes and another instruction.
Also am I supposed to add a REX prefix to these for 64-bit operation or just REX.R for the 9-16 registers?

Mode and operand size prefix. In 16 bit mode, 81 /2 will be adc rm16, imm16. In 32 or 64 bit mode, it will be adc rm32, imm32. Unless you add the operand size override, then they switch places.
To make it adc rm64, imm32 (there is no adc rm64, imm64), it needs an REX.W prefix, REX.R is useless since there is no r operand, REX.B/X will just allow you to use extended registers as (part of) the rm operand, and don't change the operand size. So for example adc r8d, 0xDEADBEEF is valid and would be 41 81 D0 EF BE AD DE.

Related

Determining when NASM can infer the size of the mov operation

Something has got me confused in x86 assembly for a while, it's how/when can NASM infer the size of the operation, here's an example:
mov ebx, [eax]
Here we are moving the 4 bytes stored at the address held in eax into ebx. The size of the operation is inferred as 4 bytes because the register is 32 bits.
However, this operation doesn't get inferred and throws a compile error:
mov [eax], 123456
Of course the solution is this:
mov dword [eax], 123456
Which will move the 32 representation of the number 123456 into the bytes stored at the address held at eax.
But this confuses me, surely it can see eax is 32 bit, so shouldn't it assume I want to store it as a 32 bit value without me having to specify dword after the mov?
Surely if I wanted to put the 16 bit representation of 12345 (smaller number to fit in 16 bits) into eax I would do this:
mov ax, 12345
The operand-size would be ambiguous (and so must be specified) for any instruction with a memory destination and an immediate source. (Neither operand actually being a register, even if using one or more in an addressing mode.)
Address-size and operand-size are separate attributes of an instruction.
Quoting what you said in a comment on another answer, since I think this gets at the core of your confusion:
I would expect mov [eax], 1 to set the 4 bytes held in memory address eax to the 32 bit representation of 1
The BYTE/WORD/DWORD [PTR] annotation is not about the size of the memory address; it's about the size of the variable in memory at that address. Assuming flat 32-bit addressing, addresses are always four bytes long, and therefore must go in Exx registers. So, when the source operand is an immediate value, the dword (or whatever) annotation on the destination operand is the only way the assembler can know whether it's supposed to modify 1, 2, or 4 bytes of RAM.
Perhaps it will help if I demonstrate the effect of these annotations on machine code:
$ objdump -d -Mintel test.o
...
0: c6 00 01 mov BYTE PTR [eax], 0x1
3: 66 c7 00 01 00 mov WORD PTR [eax], 0x1
8: c7 00 01 00 00 00 mov DWORD PTR [eax], 0x1
(I've adjusted the spacing a bit compared to how objdump actually prints it.)
Take note of two things: (1) the three different operand prefixes produce three different machine instructions, and (2) using a different prefix changes the length of the source operand as emitted into the machine code.
mov [eax], 123456
This instruction would use immediate addressing for the source operand and indirect addressing for the destination operand i.e. place the decimal 123456 into the memory address stored in register eax, as you pointed out but the memory address to which eax points does not itself have to be 32 bits in size. NASM can not infer the size of the destination operand. The size of the pointer in register eax is 32 bits.
Address-size and operand-size are totally separate attributes of an instruction.
Surely if I wanted to put the 16 bit representation of 12345 into eax I would do this:
mov ax, 12345
Yes but here you are using immediate addressing for the source operand and register addressing for the destination operand. The assembler can infer the amount of data you wish to move from the size of the destination register (16 bits in the case of the AX register, leaving the upper 2 bytes of the full EAX unmodified so you're not actually setting 32-bit EAX to that value).
compile error
I think you meant assembly error :)
In your first case it can determine it without problems, since EBX is a 32bit register. But in the second one you're using EAX as an address, not as a destination register so nasm developers took the safe route and make the developer choose the size.
If you did mov [eax], 1, what could nasm determine from that? Do you want to set the byte, 16bit or 32bit block of memory to 1? It is totally unknown. This is why it's better to force the developer to state the size.
It would be entirely different if you said mov eax, 123456 since then the destination is a register.

What Does Assembly Instruction Shift Do?

I came across a pretty interesting
article that demonstrated how to remove nullbyte characters from shellcode. Among the techniques used, the assembly instructions shl and shr seemed to occupy a rather important role in the code.
I realize that the assembly instructions mov $0x3b, %rax and mov $59, %rax each actually generate the machine code instructions 48 c7 c0 3b 00 00 00. So to cope for this, the author instead uses mov $0x1111113b, %rax to fill the register with the system call number, which generates instead the machine code 48 c7 c0 3b 11 11 11, which successfully removes nullbytes.
Unfortunately, the code still doesn't execute because syscall treats 3b 11 11 11 as an illegal instruction, or this causes the code to seg fault. So what the author then did was shift %rax back and forth 56 bytes with the commands
shl $0x38, %rax
shr $0x38, %rax
After this shift, the code executes perfectly. What I want to know is how the shift instructions fixes the 48 c7 c0 3b 11 11 11 issue, and somehow makes %rax proper and syscall'able. I know that the shl/shr shifts bits left and right, meaning that shifting left moves the bits up into higher bits, and shifting right makes them lower again, because binary is read right to left. But how does this at all change the code and make it executable? Doesn't shifting back and forth essentially change nothing, putting the shifted bits exactly back where they were in the beginning?
My only theory is that shifting bits away leaves behind zeros. But I still don't see how shifting %rax forward and then back fixes the solution, because wouldn't it bring back the 11 11 11 section anyway?
Anyways, I thought this was interesting as I had never seen the shift operands before today. Thanks in advance.
Shifting is a lossy operation - if bits are shifted outside of the register, they just disappear. (Sometimes one of them is stored in a carry flag, but that's not important here.) See http://en.wikibooks.org/wiki/X86_Assembly/Shift_and_Rotate#Logical_Shift_Instructions .
The shift left (shl) operation does this:
0x000000001111113b << 0x38 = 0x3b00000000000000
The 0x111111 part would have occupied bit 64, 65, 66 etc., but %rax is a 64-bit register, so those bits vanish. Then, the logical shift right (shr) operation does this:
0x3b00000000000000 >> 0x38 = 0x000000000000003b
Giving you the number that you want. And that's all there is to it.

x64 opcodes and scaled byte index

I think I'm getting the Mod R/M byte down but I'm still confused by the effective memory address/scaled indexing byte. I'm looking at these sites: http://www.sandpile.org/x86/opc_rm.htm, http://wiki.osdev.org/X86-64_Instruction_Encoding. Can someone encode an example with the destination address being in a register where the SIB is used? Say for example adding an 8-bit register to an address in a 8-bit register with SIB used?
Also when I use the ModR/M byte of 0x05 is that (*) relative to the current instruction pointer? Is it 32 or 64 bits when in 64 bit mode?'
Is the SIB always used with a source or destination address?
A memory address is never in an 8-bit register, but here's an example of using SIB:
add byte [rax + rdx], 1
This is an instance of add rm8, imm8, 80 /0 ib. /0 indicates that the r field in the ModR/M byte is zero. We must use a SIB here but don't need an immediate offset, so we can use 00b for the mod and 100b for the rm, to form 04h for the ModR/M byte (44h and 84h also work, but wastes space encoding a zero-offset). Looking in the SIB table now, there are two registers both with "scale 1", so the base and index are mostly interchangeable (rsp can not be an index, but we're not using it here). So the SIB byte can be 10h or 02h.
Just putting the bytes in a row now:
80 04 10 01
; or
80 04 02 01
Also when I use the ModR/M byte of 0x05 is that (*) relative to the current instruction pointer? Is it 32 or 64 bits when in 64 bit mode?
Yes. You saw the note, I'm sure. So it can be either, depending on whether you used an address size override or not. In every reasonable case, it will be rip + sdword. Using the other form gives you a truncated result, I can't immediately imagine any circumstances under which that makes sense to do (for general lea math sure, but not for pointers). Probably (this is speculation though) that possibility only exists to make the address size override work reasonably uniformly.
Is the SIB always used with a source or destination address?
Depends on what you mean. Certainly, if you have a SIB, it will encode a source or destination (because what else is there?) (you might argue that the SIB that can appear in nop rm encodes nothing because nop has neither sources nor destinations). If you mean "which one does it encode", it can be either one. Looking over all instructions, it can most often appear in a source operand. But obviously there are many cases where it can encode the destination - example: see above. If you mean "is it always used", well no, see that table that you were looking at.

Acquring Processor ID in Linux

On Microsoft Windows you can get Processor ID (not Process ID) via WMI which is based in this case (only when acquiring Processor ID) on CPUID instruction
Is there a similar method to acquire this ID on Linux ?
I do not know what WMI is and MS-Windows "CPUID instruction", since I do not know or use MS-Windows (few users here do). So I cannot say for sure if this is offering the same information, but have a try with cat /proc/cpuinfo. If you require a specific value you can grep that out easily.
If you need do to this from within a program then you can use the file utils to read such information. Always keep in mind one of the most basic principles of 'unix' style operating systems: everything is a file.
For context of the OP's question, ProcessorID value returned by WMI is documented thus:
Processor information that describes the processor features. For an
x86 class CPU, the field format depends on the processor support of
the CPUID instruction. If the instruction is supported, the property
contains 2 (two) DWORD formatted values. The first is an offset of
08h-0Bh, which is the EAX value that a CPUID instruction returns with
input EAX set to 1. The second is an offset of 0Ch-0Fh, which is the
EDX value that the instruction returns. Only the first two bytes of
the property are significant and contain the contents of the DX
register at CPU reset—all others are set to 0 (zero), and the contents
are in DWORD format.
As an example, on my system:
C:\>wmic path Win32_Processor get ProcessorId
ProcessorId
BFEBFBFF000206A7
Note that the ProcessorID is simply a binary-encoded format of information usually available in other formats, specifically the signature (Family/Model/Stepping/Processor type) and feature flags. If you only need the information, you may not actually need this ID -- just get the already-decoded information from /proc/cpuinfo.
If you really want these 8 bytes, there are a few ways to get the ProcessorID in Linux.
With root/sudo, the ID is contained in the output of dmidecode:
<snip>
Handle 0x0004, DMI type 4, 35 bytes
Processor Information
Socket Designation: CPU Socket #0
Type: Central Processor
Family: Other
Manufacturer: GenuineIntel
ID: A7 06 02 00 FF FB EB BF
<snip>
Note the order of bytes is reversed: Windows returns the results in Big-Endian order, while Linux returns them in Little-Endian order.
If you don't have root permissions, it is almost possible to reconstruct the ProcessorID from /proc/cpuinfo by binary-encoding the values it returns. For the "signature" (the first four bytes in Windows/last four bytes in Linux) you can binary encode the Identification extracted from /proc/cpuinfo to conform to the Intel Documentation Figure 5-2 (other manufacturers use it for compatibility).
Stepping is in bits 3-0
Model is in bits 19-16 and 7-4
Family is in bits 27-20 and 11-8
Processor type is in bits 13-12 (/proc/cpuinfo doesn't tell you this, assume 0)
Similarly, you can populate the remaining four bytes by iterating over the feature flags (flags key in /proc/cpuinfo) and setting bits as appropriate per Table 5-5 of the Intel doc linked above.
Finally, you can install the cpuid package (e.g., on Ubuntu, sudo apt-get install cpuid). Then by running the cpuid -r (raw) command you can parse its output. You would combine the values from the EAX and EDX registers for an initial EAX value of 1:
$ cpuid -r
CPU 0:
0x00000000 0x00: eax=0x0000000d ebx=0x756e6547 ecx=0x6c65746e edx=0x49656e69
0x00000001 0x00: eax=0x000206a7 ebx=0x00020800 ecx=0x9fba2203 edx=0x1f8bfbff
<snip>

Linux signal masks - what do they mean though?

How can you store 32 signals inside a 16 bit mask?
SigPnd: 0000000000000000
ShdPnd: 0000000000004000
SigBlk: 0000010000017003
SigIgn: 0000000000381000
How do I interpret the SigIgn for example? I read the proc documentation but I don't get how to interpret what the actual bits mean.
Not sure where you got the "32 signals inside a 16 bit mask" information from but it is wrong as far as I know.
Assuming each line is hex then each line is 8 bytes or 64 bits. The lower 4 bytes (32 bits) are standard signals. The upper 32 bits are posix realtime signals. (It's actually a little more convoluted than that - see man (7) signal and SIGRTMAX and SIGRTMIN for the low down.)
So in the SigIgn mask you asked about everything is off but a couple of things in the lower 3 bytes: 38 10 00. In the lowest order byte, 00, no signals are ignored. In the next byte, the hex 10 converts to 00010000 in binary. So the 5th bit in that byte is on. Likewise hex 38 converts to binary 00111000. Putting the 3 bytes together as a string of binary we get:
001110000001000000000000
So counting from the right we can see that bits 13 20 21 22 are ON and therefore ignored. If you go back to man (7) signal you can see the table for the signal values. The values are broken down by architecture so, assuming you are on a ix86 machine, the signal values represent that SIGPIPE, SIGTSTP, SIGTTIN and SIGTTOU signals are being ignored.

Resources