Using 'db','dw' in MVC++ assembler adds - model-view-controller

What should I use instead of
__asm
{
db 0EAh
dw 0000h
dw 0FFFFh
}
( http://msdn.microsoft.com/en-us/library/h70hd396.aspx )
in MVC++?

_asm {
mov ax, 40h
mov ds, ax
mov word ptr ds:[72h], 1234h
jmp dword ptr cs:0ffff0000h
}
Thanks to #gusbro's comment I finally understand what you are trying to do. I'm not sure if this will work since I don't have a windows machine to test this, but you should give it a try.
warm is a far call to FFFF:0000h with 40:72h set to 1234h
cold is a far call to FFFF:0000h with 40:72h set to 0

You can emit opcodes with this intrinsic function :
__emit(int opcode)
You might be able to execute your code by secuentially emmiting the opcodes.
However, I don't think you will succeed in rebooting your machine this way...

Related

Cannot modify data segment register. When tried General Protection Error is thrown

I have been trying to create an ISR handler following this
tutorial by James Molloy but I got stuck. Whenever I throw a software interrupt, general purpose registers and the data segment register is pushed onto the stack with the variables automatically pushed by the CPU. Then the data segment is changed to the value of 0x10 (Kernel Data Segment Descriptor) so the privilege levels are changed. Then after the handler returns those values are poped. But whenever the value in ds is changed a GPE is thrown with the error code 0x2544 and after a few seconds the VM restarts. (linker and compiler i386-elf-gcc , assembler nasm)
I tried placing hlt instructions in between instructions to locate which instruction was throwing the GPE. After that I was able to find out that the the `mov ds,ax' instruction. I tried various things like removing the stack which was initialized by the bootstrap code to deleting the privilege changing parts of the code. The only way I can return from the common stub is to remove the parts of my code which change the privilege levels but as I want to move towards user mode I still want them to stay.
Here is my common stub:
isr_common_stub:
pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
xor eax,eax
mov ax, ds ; Lower 16-bits of eax = ds.
push eax ; save the data segment descriptor
mov ax, 0x10 ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call isr_handler
xor eax,eax
pop eax
mov ds, ax ; This is the instruction everything fails;
mov es, ax
mov fs, ax
mov gs, ax
popa
iret
My ISR handler macros:
extern isr_handler
%macro ISR_NOERRCODE 1
global isr%1 ; %1 accesses the first parameter.
isr%1:
cli
push byte 0
push %1
jmp isr_common_stub
%endmacro
%macro ISR_ERRCODE 1
global isr%1
isr%1:
cli
push byte %1
jmp isr_common_stub
%endmacro
ISR_NOERRCODE 0
ISR_NOERRCODE 1
ISR_NOERRCODE 2
ISR_NOERRCODE 3
...
My C handler which results in "Received interrupt: 0xD err. code 0x2544"
#include <stdio.h>
#include <isr.h>
#include <tty.h>
void isr_handler(registers_t regs) {
printf("ds: %x \n" ,regs.ds);
printf("Received interrupt: %x with err. code: %x \n", regs.int_no, regs.err_code);
}
And my main function:
void kmain(struct multiboot *mboot_ptr) {
descinit(); // Sets up IDT and GDT
ttyinit(TTY0); // Sets up the VGA Framebuffer
asm volatile ("int $0x1"); // Triggers a software interrupt
printf("Wow"); // After that its supposed to print this
}
As you can see the code was supposed to output,
ds: 0x10
Received interrupt: 0x1 with err. code: 0
but results in,
...
ds: 0x10
Received interrupt: 0xD with err. code: 0x2544
ds: 0x10
Received interrupt: 0xD with err. code: 0x2544
...
Which goes on until the VM restarts itself.
What am I doing wrong?
The code isn't complete but I'm going to guess what you are seeing is a result of a well known bug in James Molloy's OSDev tutorial. The OSDev community has compiled a list of known bugs in an errata list. I recommend reviewing and fixing all the bugs mentioned there. Specifically in this case I believe the bug that is causing problems is this one:
Problem: Interrupt handlers corrupt interrupted state
This article previously told you to know the ABI. If you do you will
see a huge problem in the interrupt.s suggested by the tutorial: It
breaks the ABI for structure passing! It creates an instance of the
struct registers on the stack and then passes it by value to the
isr_handler function and then assumes the structure is intact
afterwards. However, the function parameters on the stack belongs to
the function and it is allowed to trash these values as it sees fit
(if you need to know whether the compiler actually does this, you are
thinking the wrong way, but it actually does). There are two ways
around this. The most practical method is to pass the structure as a
pointer instead, which allows you to explicitly edit the register
state when needed - very useful for system calls, without having the
compiler randomly doing it for you. The compiler can still edit the
pointer on the stack when it's not specifically needed. The second
option is to make another copy the structure and pass that
The problem is that the 32-bit System V ABI doesn't guarantee that data passed by value will be unmodified on the stack! The compiler is free to reuse that memory for whatever purposes it chooses. The compiler probably generated code that trashed the area on the stack where DS is stored. When DS was set with the bogus value it crashed. What you should be doing is passing by reference rather than value. I'd recommend these code changes in the assembly code:
irq_common_stub:
pusha
mov ax, ds
push eax
mov ax, 0x10 ;0x10
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
push esp ; At this point ESP is a pointer to where GS (and the rest
; of the interrupt handler state resides)
; Push ESP as 1st parameter as it's a
; pointer to a registers_t
call irq_handler
pop ebx ; Remove the saved ESP on the stack. Efficient to just pop it
; into any register. You could have done: add esp, 4 as well
pop ebx
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
popa
add esp, 8
sti
iret
And then modify irq_handler to use registers_t *regs instead of registers_t regs :
void irq_handler(registers_t *regs) {
if (regs->int_no >= 40) port_byte_out(0xA0, 0x20);
port_byte_out(0x20, 0x20);
if (interrupt_handlers[regs->int_no] != 0) {
interrupt_handlers[regs->int_no](*regs);
}
else
{
klog("ISR: Unhandled IRQ%u!\n", regs->int_no);
}
}
I'd actually recommend each interrupt handler take a pointer to registers_t to avoid unnecessary copying. If your interrupt handlers and the interrupt_handlers array used function that took registers_t * as the parameter (instead of registers_t) then you'd modify the code:
interrupt_handlers[r->int_no](*regs);
to be:
interrupt_handlers[r->int_no](regs);
Important: You have to make these same type of changes for your ISR handlers as well. Both the IRQ and ISR handlers and associated code have this same problem.

OSX gettimeofday syscall on x86_64 seems to not work

I'm making a call to gettimeofday via the syscall instruction using 64bit code.
I can't get any results back and am getting told via Dtrace that the call worked with no errors, but the registers I get back from the call are garbage.
I do the following:
lea rdi, [rel timeval] ;buffer for 16bytes
mov rsi, 0 ;no need of timezone
mov rax, 0x2000074 ;gettimeofday
syscall
On return rax is neither 0 nor -1, and the buffer never gets any data.
Please can somebody check this and see if they can get a working call. I've no idea what is going on.
Best Regards
Chris
ps this is the example code I just tried, it dosn't return anything but 0.
SECTION .text
global _main
_main:
lea rdi, [rel buffer]
mov rsi, 0
mov rax, 0x2000074
syscall
mov rdi, [rel buffer]
mov rax, 0x2000001
syscall
SECTION .data
buffer:
times 16 db 0
According to the APIs, you need to point:
1) RDI to the timeval structure:
_STRUCT_TIMEVAL
{
__darwin_time_t tv_sec; /* seconds */
__darwin_suseconds_t tv_usec; /* and microseconds */
};
DarwinTime is a QWORD and DarwinSuSeconds is a DWORD.
2) RSI to the timezone structure.
Just point that to a 2xQWORD scratch buffer if you don't like its output.
3) RDX to the mach_absolute_time structure
This is a 1xQWORD buffer
Setting either of the above RSI, RDX, RDI to 0x0 rather than pointers might be getting rejected as it can trigger an internal exception. (Check if the return value is -EFAULT.)
Also note that POSIX deprecates gettimeofday in favour of clock_gettime (which has a seconds / nanosecond time struct), so you might want to use that instead.

masm FPU to fasm FPU cannot translate and it does not work

I have this code in masm to deal with the FPU and it works great
in this code I get a number from 2 different textboxes and then divide them and then output the results to another textbox
this is the data that is local
LOCAL variable1 :QWORD
LOCAL variable2 :QWORD
LOCAL variable3 :QWORD
LOCAL string1[20]:BYTE
LOCAL string2[20]:BYTE
LOCAL string3[20]:BYTE
this is the code
invoke GetDlgItemText,hWin,textbox1,addr string1,9
invoke StrToFloat,addr string1,addr variable1
invoke GetDlgItemText,hWin,textbox2,addr string2,9
invoke StrToFloat,addr string2,addr variable2
finit
fld variable1
fld variable2
fdiv
fstp variable3
invoke FloatToStr,variable3,addr string3
invoke SetDlgItemText,hWin,textbox3,addr string3
I am trying to convert the code to fasm
this is what I have so far but it is not working the textbox3 just says 0
this is the data (this is not local data because I have not learned how to do that in fasm yet)
v1 dq ?
v2 dq ?
v3 dd ?
v4 rb 20
this is the code
invoke GetDlgItemTextA,[hWin],textbox1,addr v1,100
invoke GetDlgItemTextA,[hWin],textbox2,addr v2,100
finit
fld qword [v1]
fld qword [v2]
fdivp
fstp qword [v3]
cinvoke wsprintfA,addr v4,"%u",[v3]
invoke SetDlgItemTextA,[hWin],textbox3,addr v4
I know this code is not right because I am not converting the text to float at the begining but i do not know how to
I also tried a simpler version and it did not work either
mov [v1],5.3
mov [v2],7.1
finit
fld [v1]
fld [v2]
fdivp
fstp [v3]
cinvoke wsprintfA,addr v4,"%u",[v3]
invoke SetDlgItemTextA,[hWin],maximumoutputpowertext,addr v4
so my question is can someone please show me how to read a number from 2 different textboxes and then divide them and the return the result to another textbox
using fasm code
thank you
There are several problems in the demonstrated code.
At first, it is not clear what StrToFloat procedure is? Is it imported from some DLL or it is part of the code, or some other library?
If this procedure is imported, it has to be imported in the FASM program as well. Else it can be written from scratch or ported in source form from the MASM program.
The immediate show stopper here is mov [v1], FLOAT_CONSTANT instruction. The reason is that v1 is qword variable, but mov can moves only dword immediate values (even in 64bit environment).
mov dword [v1], 5.0 works fine, but of course it is not what the OP needs.
Floating qword constants can be defined immediately in compile time as well: v1 dq 3.2
If we really want to set some qword floating constant in run time, we have to make it in two instructions following way:
a = 5.3
mov dword [var], (a and $ffffffff)
mov dword [var+4], (a shr 32)
var dq ?
The original FPU code in FASM syntax will be:
finit
fld [variable1]
fdiv [variable2]
fstp [variable3]

Illegal instruction in Assembly

I really do not understand why this simple code works fine in the first attempt but when
putting it in a procedure an error shows:
NTVDM CPU has encountered an illegal instruction
CS:db22 IP:4de4 OP:f0 ff ff ff ff
The first code segment works just fine:
.model small
.stack 100h
.code
start:
mov ax,#data
mov ds,ax
mov es,ax
MOV AH,02H ;sets cursor up
MOV BH,00H
MOV DH,02
MOV DL,00
INT 10H
EXIT:
MOV AH,4CH
INT 21H
END
However This generates an error:
.model small
.stack 100h
.code
start:
mov ax,#data
mov ds,ax
mov es,ax
call set_cursor
PROC set_cursor near
MOV AH,02H ;sets cursor up
MOV BH,00H
MOV DH,02
MOV DL,00
INT 10H
RET
set_cursor ENDP
EXIT:
MOV AH,4CH
INT 21H
END
Note: Nothing is wrong with windows config. I have tried many sample codes that work fine
Thanks
You left out a JMP:
call set_cursor
jmp EXIT ; <== you forgot this part
PROC set_cursor near
What's happening is that after call set_cursor, you're then falling through to the proc and and executing it again, then when you hit the ret it pops the stack and you jump to, well, who knows?
Edit: As someone else pointed out, you're better off putting your PROC after your main code ends, instead of sticking it in the middle and jumping around it. But you've probably figured that out already :)
You should move the code of the procedure after the part where you exit the program (or follow egrunin's advice).
The reason for your segfault is that the code in the procedure is executed again after you first call it. During the second execution the code crashes on RET because there is no valid return address on the stack.

save inline asm register value to C pointer, can get it on GCC but not VC

for the sake of simplicity ill just paste an example instead of my entire code which is a bit huge. while im porting my code to VC++ instead of using GCC i need to rewrite a few inline assembly functions that receive pointers and save values on those pointers.
imagine cpuid for example:
void cpuid( int* peax, int* pebx, int* pecx, int* pedx, int what ){
__asm__ __volatile__( "cpuid" : "=a" (*peax), "=b" (*pebx), "=c" (*pecx), "=d" (*pedx) : "a" (what) );
}
that will just work, it will save the values on the registers "returned" by cpuid on the pointers that i passed to the function.
can the same be done with the inline assembler for VC?
so far the exact same function signature but with:
mov eax, what;
cpuid;
mov dword ptr [peax], eax;
etc
wont work, peax will have the same value it had before calling the function.
thanks in advance.
Tough to see because it is just a snippet, plus it could be called from C++ code / thiscall.
It might have to be 'naked' ( __declspec(naked) ) in some cases.
It won't port as VC is dropping x64 inline asm support iirc.
Use the __cpuid or __cpuidex intrinsic and enjoy.
mov eax, what;
cpuid;
mov ecx, dword ptr peax;
mov [ecx], eax;
will work.
Good luck!

Resources