Division of double word in MASM - division

HDIVIDEND DW 1234H
LDIVIDEND DW 5678H
DIVISOR DW 1234H
MOV AX,LDIVIDEND
MOV DX,HDIVIDEND
DIV DIVISOR
I am getting an "Illeagal instruction" on running a masm code at the instruction
DIV DIVISOR
Where HDIVIDEND is the higher order bytes of dividend in 16 bit. And divisor is 16 bit.

Yes, the program you had written should have assembled correctly. Perhaps you had made a mistake in another part of your file, which would thus be the cause of your "illegal instruction". Or maybe you should download a newer version of MASM as it might have temporarily malfunctioned. Anyway, here is the working code, assembled and linked with MASM64 for Windows (should still work with MASM32):
dseg segment para 'DATA'
hdividend dw 1234h
ldividend dw 5678h
divisor dw 1234h
dseg ends
cseg segment para 'CODE'
start proc
mov ax, ldividend
mov dx, hdividend
div divisor
start endp
cseg ends
end
And the output:
C:\Masm64>bin\ml64.exe /c division.asm
Microsoft (R) Macro Assembler (x64) Version 8.00.50727.215
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: division.asm
C:\Masm64>bin\link.exe /subsystem:windows /entry:start division.obj
Microsoft (R) Incremental Linker Version 8.00.50727.215
Copyright (C) Microsoft Corporation. All rights reserved.
Hope this helps.

Related

Valgrind reports "invalid write" at "X bytes below stack pointer"

I'm running some code under Valgrind, compiled with gcc 7.5 targeting an aarch64 (ARM 64 bits) architecture, with optimizations enabled.
I get the following error:
==3580== Invalid write of size 8
==3580== at 0x38865C: ??? (in ...)
==3580== Address 0x1ffeffdb70 is on thread 1's stack
==3580== 16 bytes below stack pointer
This is the assembly dump in the vicinity of the offending code:
388640: a9bd7bfd stp x29, x30, [sp, #-48]!
388644: f9000bfc str x28, [sp, #16]
388648: a9024ff4 stp x20, x19, [sp, #32]
38864c: 910003fd mov x29, sp
388650: d1400bff sub sp, sp, #0x2, lsl #12
388654: 90fff3f4 adrp x20, 204000 <_IO_stdin_used-0x4f0>
388658: 3dc2a280 ldr q0, [x20, #2688]
38865c: 3c9f0fe0 str q0, [sp, #-16]!
I'm trying to ascertain whether this is a possible bug in my code (note that I've thoroughly reviewed my code and I'm fairly confident it's correct), or whether Valgrind will blindly report any writes below the stack pointer as an error.
Assuming the latter, it looks like a Valgrind bug since the offending instruction at 0x38865c uses the pre-decrement addressing mode, so it's not actually writing below the stack pointer.
Furthermore, at address 0x388640 a similar access (and again with pre-decrement addressing mode) is performed, yet this isn't reported by Valgrind; the main difference being the use of an x register at address 0x388640 versus a q register at address 38865c.
I'd also like to draw attention to the large stack pointer subtraction at 0x388650, which may or may not have anything to do with the issue (note this subtraction makes sense, given that the offending C code declares a large array on the stack).
So, will anyone help me make sense of this, and whether I should worry about my code?
The code looks fine, and the write is certainly not below the stack pointer. The message seems to be a valgrind bug, possibly #432552, which is marked as fixed. OP confirms that the message is not produced after upgrading valgrind to 3.17.0.
code declares a large array on the stack
should [I] worry about my code?
I think it depends upon your desire for your code to be more portable.
Take this bit of code that I believe represents at least one important thing you mentioned in your post:
#include <stdio.h>
#include <stdlib.h>
long long foo (long long sz, long long v) {
long long arr[sz]; // allocating a variable on the stack
arr[sz-1] = v;
return arr[sz-1];
}
int main (int argc, char *argv[]) {
long long n = atoll(argv[1]);
long long v = foo(n, n);
printf("v = %lld\n", v);
}
$ uname -mprsv
Darwin 20.5.0 Darwin Kernel Version 20.5.0: Sat May 8 05:10:33 PDT 2021; root:xnu-7195.121.3~9/RELEASE_X86_64 x86_64 i386
$ gcc test.c
$ a.out 1047934
v = 1047934
$ a.out 1047935
Segmentation fault: 11
$ uname -snrvmp
Linux localhost.localdomain 3.19.8-100.fc20.x86_64 #1 SMP Tue May 12 17:08:50 UTC 2015 x86_64 x86_64
$ gcc test.c
$ ./a.out 2147483647
v = 2147483647
$ ./a.out 2147483648
v = 2147483648
There are at least some minor portability concerns with this code. The amount of allocatable stack memory for these two environments differs significantly. And that's only for two platforms. Haven't tried it on my Windows 10 vm but I don't think I need to because I got bit by this one a long time ago.
Beyond OP issue that was due to a Valgrind bug, the title of this question is bound to attract more people (like me) who are getting "invalid write at X bytes below stack pointer" as a legitimate error.
My piece of advice: check that the address you're writing to is not a local variable of another function (not present in the call stack)!
I stumbled upon this issue while attempting to write into the address returned by yyget_lloc(yyscanner) while outside of function yyparse (the former returns the address of a local variable in the latter).

Setup / Errors with Floating Point on TI AM3517 Cortex-A8

I'm getting an undefined instruction exception when executing:
0xED2D8B0E VPUSH {D8-D14}
(Note: The statement was generated by the compiler as part of C language function entry protocol.)
Initialization code:
;; Initialize VFP (if needed).
;; BL __iar_init_vfp HJ REMOVED AND REPLACED WITH BELOW
MRC p15, #0, r1, c1, c0, #2 ; r1 = Access Control Register
ORR r1, r1, #(0xf << 20) ; enable full access for p10,11
MCR p15, #0, r1, c1, c0, #2 ; Access Control Register = r1
MOV r1, #0
MCR p15, #0, r1, c7, c5, #4 ; flush prefetch buffer because of FMXR below
; and CP 10 & 11 were only just enabled
; Enable VFP itself
MOV r0,#0x40000000
FMXR FPEXC, r0 ; FPEXC = r0
I get the undefined exception when the target FPU is set up as VFPv3 or VFPV3 + NEON.
The initialization code is placed in the "cstartup.c" file, at the __iar_program_start and ?cstartup code, following this code snippet:
MRC p15,0,R1,C1,C0,0
LDR R0,=CP_DIS_MASK ;; 0xFFFFEFFA
AND R1,R1,R0
ORR R1,R1,#(1<<12)
MCR p15,0,R1,C1,C0,0
Registers (before VPUSH):
CPSR: 0x80000113
APSR: 0x80000000
SPSR: 0x000001D3
Tools:
IAR Embedded Workbench IDE & Compiler - 7.40
I-Jet debugging probe
Zoom AM3517 eval board
TI AM35X Cortex-A8 processor
Questions:
In the initialization code above, which statements are required for
NEON and which for VFP?
Are there any initialization instructions I'm missing for NEON and
VFP initialization?
Are there statements I need to place in the macro file for the debug
probe?
The code presented in the question correctly initializes the floating point processor on a Cortex-A8 processor.
The issue of getting undefined instruction exception (which led up to this question), was caused by the O.S. writing an invalid value to the FPEXC register, causing the Floating Point Processor to be disabled.

VS2013 WinFX.targets mangled, can't open new/old project files

I have a bit of a strange problem and no amount of googling has given me any answers or solutions. I'm not entirely sure if it belongs on Stack Overflow, but since it involves VS/NET Framework, I thought I'd give it a try.
Whenever I try to create a new project or open an existing project in Visual Studio 2013, I get the following error:
"Unable to read the project file ".vcxproj".
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.WinFx.targets(654,31): The project file could not be loaded. ';' is an unexpected token. The expected token is '='. Line 654, position 31."
I've discovered that the mentioned Microsoft.WinFx.targets file is damaged. Line 654 through 665 is filled with random binary data, beginning at column 31 as in the error message.
I have no clue what to do now. I can't reinstall .NET Framework 4.0 because it's already a part of Windows 8 and thus I can't run the standalone/web installers. I can't delete the file because it's protected by TrustedInstaller (which also leads me to the fact that I have no clue how or where to get a non-damaged copy of the file).
Just a bit of background info: I recently installed Windows 8, then upgraded to 8.1. I initially had Visual Studio 2013 Ultimate RC installed which worked at first. I hadn't used it in a week or two when I tried to load the Quake 3 source and first encountered the error. I thought it was because I was using an RC, so I uninstalled VS and installed VS13 Professional. Of course, this didn't solve my problem.
Any tips on how to proceed or insight into what may have happened?
The random data is the following:
;;Z<Ö<Û<æ<=F=Q=•=_>e>j>s>€>œ>«>°>¹>È>Ô>Ù>â>ñ>ö>ÿ>???+?0?9?H?M?V?i?n?w?Š??˜?«?°?¹?Ì?Ñ?Ú?í?ò?û? € ¼ 000/040=0P0U0^0q0v00’0—0 0³0¸0½0|2‚2“2™2½2Å23/373A3y3—3¸3¾3å3ð344Ð4à4 595C5g5†5Œ5—5ž5©5¾5ô586E6J6a6r6w6‰6¨6Ä6Û6÷677-7#7M7|7š7+8%9-9J9Z9};†;9>Q>]>b>€>°>(?ñ? ü ˆ001Ò1Ø1ã1ê12
222i2o2Œ2“2™2¶2É23:3D3O3“3í34,4#4v4Ú45D5H5L5P5T5C6^6Ü6¿7É7é7'8q8w8}8Š8“8™8H:Q:X:]:c:É:Ï:;f;y;„;Œ;”;œ;¤;¬;´;¼;Ä;Ì;Ô;Ü;ä;ì;ô;ü;<<<^>d>j>p>v>†>Œ>’>˜>ž>¤>µ>½>Ý>å>ú> ??? ?C?J?c?…?”?œ?ô?ø?   ¨ )000¬0½0Í0Ø0þ011#1/151=1C1S1Y1e1k1Ž1™1£1¨1¿1Ñ1Þ1é1ï1ø12222#2)23292?2Ð2Ø2ï2Ò34%4+464a4‰44”4Æ4â4ô45555%5*545#5F5L5V5\5b5æ5î56è6>•> >Ë>ð>? ?m?¬?¹? ° d ‹0Ø0â0°1ú12ë2:3D3'4E4W4¦4å4ò4Í56$6û6E7V7-8|8†8a9~9‘9£9â9ï9Á:;;æ;0>Ÿ>¬>‡?Ô?Þ? À € µ0ÿ01ç162#2F3Q3Õ3à344c4}4°4ó45Å5!616x6…6»6j7è7ý78g8È8Î8Þ8è899A9K9Æ9×9è9ù9M:’:ñ:;U;e<<ï<=y=•=æ=B>U>w>¶>?)?}? Ð | ›0·011M1Ç1ã172Œ2Ÿ2!3f3Å3Ù3-4K5g5á5ý5w6“6ç6C7V7ò7188¤8ô8: :Ž:ª:;4;…;Ú;í;
<ì>?p?w?Ø?è?ò? à x 0%0K0U0Ô0å0ö01n1³12*2z23©3434¡4½45j5}5Ÿ5Þ5A6U6©6Ê7æ78|8ö89f9»9Î9ð9/:’:¦:ö: <%<“<¯<=9=Š=ß=ò=>$>??y?º? ð # Â0,1o1€1*2B2´2/373a3q3~36ñ6 708ÿ8ù9:(:3:·<=¼=Ù>d?y? L Ÿ0ó0K1Œ1›1©1Þ1{4U5ƒ5”6'7q9Å9:<<ˆ<ª<±<(=^=å=ì=>>°>·>8?Y?¾?Å?ç?î? h p0w0Ù0à01 1˜1©2À2$3Ê4ó4515Ï5,6C6ˆ6š6ã6767 8‚8ý8X9½91:8:Z:a:à:Ž;x<Å<6===_=f=Ø=î=>/>P>ý>˜?ç? d F0%1©1$3¨3¯3P4á4x5Ž5¯5Ï5ð56~6…6§6®6À78L899#:x:´:Ò:Ü:ã:é:);/;4;E;I<m<w<Â<÷< =^=ö=F>Ø>G?u? 0 d (0/011Ø1^2l2{2‚22š2ü23$3+3 44È4Ï4À5Ó5ñ56,6=6y6†6˜6«6É6ñ677H7M79Ã9è9:Á:ç:;2;ï<=5= # ” 171Y1|1Ž1³1ÿ1°2È2&3.373<3L3Q33464=4G4S4¥4Ï4a5§5°5¸6!7z7€7ˆ7ž7£7±7¹7É7ç7Ù809f9è9õ9M:o:º:©;0<C<<}<™<µ<Ñ<â>>>^>}>œ>»>Û>û>?:?Y? P h 000L0i0T1~12,2³2Ý2Æ3â3ÿ3Î45A5Y5ø56(6E6a6}6™6ª6ó67J788V8#99¯:Ó:Ý:(;];†;Ê;b<²<6=¥=Ó=ˆ>>P?Ò? \ h0{0™0¶0Ô0å0
1a1r1â132;2D2I2Y2^2•2 3>3E3O3[3»3å3t4º4Ã4Ð57Ø7-<Æ<Í<E=Q=>>>C>¾>’? p D 0™12+2:2W2c2l2„2Š2ª3À3À657)9o9ý9C:Ë:j;§;Ø;ø;z<–<(=Ó=#>²> € \ ª01B1J1Y1v1‚1‹1£1®1´1p2&3C5n5Í5.686V6‡6§6/7K7Ý799‘99:; ;•;¡;„< =e=û=h>³>M?•? < o1{1ð1ü1o2{2ó2ÿ2t3€3N4Z4Ï4Û4Ÿ56–618ð8°9;®;K<L=…?‘?   # 0P0v0~0$1=1Á122ä3“4Æ4X5–5©5²56a7!8|;ƒ;¸;Ë;<]=¦>ì>‘? ° $ Ô102Õ2 66<6O6‡6k7Ÿ7Ä7ò7±8 Å3ó344w4’44¸4È4å4\5 Ï3 n3 0 ‚3 # ( D45575u8_9 =.?2?6?:?>?B?F?J? P 0151?28Ï>? # å1é1í1ñ1õ1ù1ý12Y2'3?3c36†7#;c=g=k=o=s=w={==×=¥>´>Í> p ( ç1(3¾6ì8ð8ô8ø8ü8 999ž9³:Ë:Ç; € ( ï1z8ã8µ;¹;½;Á;Å;É;Í;Ñ;J<=4=X= ( t0µ1B5€7„7ˆ7Œ77”7˜7œ7ô7m8‹8±8   E8Ý8û8!9€9“9®9û<ë= ° , ’1´3¸3¼3À3Ä3È3Ì3Ð3X5ð5646ë67ô7C> À 5L588
888888.8 Ð Ñ9 à õ<#>;>,? ð ;5 <[7³9Ì:X;û=f> F99¤9k;; # 0[0b0÷1
25::¸:Õ:ó:;+;P;;œ;R<‘<ä<è<ÿ<
==L=P=˜=p>ˆ>> 0 P J0j0ó0è1ð1ô1¢2ì2ð2÷2<3#3G3Œ33—3ä3è3g485ð6ø6ü67”8˜8Ÿ8D9H9ì;<&<1<4?j?¬? # È 0 0'0 0§0(141^11º1¿1¨2¯2Ï2Ô283S3X3r3À3˜4n55Œ5·5Ä5â546<6T6X6™6Û6è677x9l:y:¢:¯:Ð:Ø:ô:ø:þ:;A;Q;À;È;Í;Ô;Ú;à;å;ë;ñ;ú; <
<<<G>R>ô>? ?'?.?5?B?K?i?¶?º?¾?Â?Æ?Ê?Î?Ò? P œ 0 0<0e0Ñ0è011O1“1š1¥1¼1
2&27344n4u4Å4Ð4ß4õ455c5k5t5|5†5¡5µ5Ë5Þ56,6i6‚6©6ö6
7‰7©782888b89–9: ::;
;7;#;L;d;j;p;w; ?&?4?:?^?d?€?¯?µ?Ê?Ð?í? ˆ :0#0[0a0‚0ˆ0Ë0$1(151W1o1w11ˆ11á1ö152U2z2†2ò23s3•3ù3.4o4…4Õ4ë4;5Q5È5p7ð7[8n88Ÿ8²8Ä89$9ø;¨>?m??é? p ” 0s0º0ü01n1„1à1ö1€2‡2ó23o3‘3494{4‘4í45_5u5ð5÷5c6…6ä67m7³7ô7
8Z8p8À8Ö8X9_9ì9(:¢:¯:È:æ:";J;è;ï;<9…> >Á>Ü>:?c?¨?´?»?î?ø? € ¸ Z0»0è0û0151P1]1j1r1†1”1¢1«155,575D5Y5_5g5o5ª5¼5Û5â5ð5!606D6Q6e6Ð6Ö6C7 7§7 88`8g8À8Í8Ø8ï8ú89 9&9.969y9Ž9—9±9Å9:::x::Ø:ß:#;Ã; <,<9E>˜>ó>X?e?v?‚?–?£?·?¿?Å?×?Ý? ˆ 80D0 0b1i1å1ì1G2t2°2×23°3Ó3h4o4©4º4í4ó4H5€5™5æ5ü5636³6à6ç67E7Ð7Ù7à7ú738E8y8 8p9w9©9Ñ9ˆ::Å:ì:¸;Ñ;«<±<¼<=9=À=>!>+>A>„>¶>Þ>p?   ð c2i2n2‘2—2œ2À2š3¤3±3Ù3ß3ü3444h4o4~4„4¨4®4¶4Ñ4×4Ý4î4ô4ú4h5v5¥5«5Å5<6G6^6ž6Ô6Þ6ä6ñ6 7.747B7G7O7U7c7h7p7v7„7‰7‘7—7¥7ª7 8'8n8s8­8²8¹8¾8Å8Ê8Ø899B9H9è9õ9û9+:1:S:Z:

smulwb assembly instruction

I'm trying to understand this code:
inline SInt32 smul32by16(SInt32 i32, SInt16 i16)
{
register SInt32 r;
asm volatile("smulwb %0, %1, %2" : "=r"(r) : "r"(i32), "r"(i16));
return r;
}
Does anybody know what this assembly instruction does?
Update:
P.S. I use objective C. and I should understand some code from assembly. That's why it's difficult for me to understand this code.
It does signed 32 bit by signed 16 bit multiplication and returns the top 32 bit of 48 bit result. The b specifies to use the bottom 16bit of the third operand.
So, translating it into pseudo code:
int_48 temp;
temp = i32*i16;
result = temp >> 16;
See here for the description of the ARM SMUL and SMULW instructions:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDIABBH.html
by using asm you can give assembler commands.
and using volatile for the reason,
volatile for the asm construct, to prevent GCC from deleting the asm statement as unused
see this link for better understanding
command inside ask instruction means :
SMULWB R4, R5, R3 ; Multiplies R5 with the bottom halfword of R3,
; extracts top 32 bits and writes to R4.

Add two 32-bit integers in Assembler for use in VB6

I would like to come up with the byte code in assembler (assembly?) for Windows machines to add two 32-bit longs and throw away the carry bit. I realize the "Windows machines" part is a little vague, but I'm assuming that the bytes for ADD are pretty much the same in all modern Intel instruction sets.
I'm just trying to abuse VB a little and make some things faster. So as an example of running direct assembly in VB, the hex string "8A4C240833C0F6C1E075068B442404D3E0C20800" is the assembly code for SHL that can be "injected" into a VB6 program for a fast SHL operation expecting two Long parameters (we're ignoring here that 32-bit longs in VB6 are signed, just pretend they are unsigned).
Along those same lines, what is the hex string of bytes representing assembler instructions that will do the same thing to return the sum of two 32-bit unsigned integers?
The hex code above for SHL is, according to the author:
mov eax, [esp+4]
mov cl, [esp+8]
shl eax, cl
ret 8
I spit those bytes into a file and tried unassembling them in a windows command prompt using the old debug utility, but I figured out it's not working with the newer instruction set because it didn't like EAX when I tried assembling something but it was happy with AX.
I know from comments in the source code that SHL EAX, CL is D3E0, but I don't have any reference to know what the bytes are for instruction ADD EAX, CL or I'd try it. (Though I know now that the operands have to be the same size.)
I tried flat assembler and am not getting anything I can figure out how to use. I used it to assemble the original SHL code and got a very different result, not the same bytes. Help?
I disassembled the bytes you provided and got the following code:
(__TEXT,__text) section
f:
00000000 movb 0x08(%esp),%cl
00000004 xorl %eax,%eax
00000006 testb $0xe0,%cl
00000009 jne 0x00000011
0000000b movl 0x04(%esp),%eax
0000000f shll %cl,%eax
00000011 retl $0x0008
Which is definitely more complicated than the source code the author provided. It checks that the second operand isn't too large, for example, which isn't in the code you showed at all (see Edit 2, below, for a more complete analysis). Here's a simple stdcall function that adds two arguments together and returns the result:
mov 4(%esp), %eax
add 8(%esp), %eax
ret $8
Assembling that gives me this output:
(__TEXT,__text) section
00000000 8b 44 24 04 03 44 24 08 c2 08 00
I hope those bytes do what you want them to!
Edit: Perhaps more usefully, I just did the same in C:
__attribute__((__stdcall__))
int f(int a, int b)
{
return a + b;
}
Compiled with -Oz and -fomit-frame-pointer it generates exactly the same code (well, functionally equivalent, anyway):
$ gcc -arch i386 -fomit-frame-pointer -Oz -c -o example.o example.c
$ otool -tv example.o
example.o:
(__TEXT,__text) section
_f:
00000000 movl 0x08(%esp),%eax
00000004 addl 0x04(%esp),%eax
00000008 retl $0x0008
The machine code output:
$ otool -t example.o
example.o:
(__TEXT,__text) section
00000000 8b 44 24 08 03 44 24 04 c2 08 00
Sure beats hand-writing assembly code!
Edit 2:
#ErikE asked in the comments below what would happen if a shift of 32 bits or greater was attempted. The disassembled code at the top of this answer (for the bytes provided in the original question) can be represented by the following higher-level code:
unsigned int shift_left(unsigned int a, unsigned char b)
{
if (b > 32)
return 0;
else
return a << b;
}
From this logic it's pretty easy to see that if you pass a value greater than 32 as the second parameter to the shift function, you'll just get 0 back.