PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Problem mit dem MOV-Befehl


assemblernewbie
09.05.2005, 11:55
Hallo,

ich habe folgendes Problem. Immer wenn ich einen Wert in ein 32-Bit Register bewege und daraufhin einen weiteren Wert in ein anderes Register werden die 4 ersten Stellen des ersten Registers auf null gesetzt.
z.B. bei folgendem Programm:
- Nach dem ersten Schritt steht korrekt 45A656 im EBX-Register
- Nach dem zweiten Schritt steht die 5 im ECX-Register, im EBX aber nur noch A656.

Der Code sieht folgendermaßen aus:

.386

stck SEGMENT STACK USE16
DW 200 DUP(0)
stck ENDS

code SEGMENT USE16 'CODE'
ASSUME CS:code

start:
MOV EBX,4564566
MOV ECX,5

MOV AX,4C00h
INT 21h

Was mache ich falsch? Vielen Dank schonmal für die Hilfe


Jan Krüger
09.05.2005, 12:14
Das sieht korrekt aus. Wer behauptet denn, dass sich nach der Zuweisung zu ECX der Wert von EBX geändert hat?

assemblernewbie
09.05.2005, 13:01
Ich versteh das alles auch nicht wirklich. Aber hab es in Codeview und mit Hilfe einer Ausgabeprozedur getestet.

Pukys
10.05.2005, 16:47
Hallo,

Der Code sieht folgendermaßen aus:

.386

stck SEGMENT STACK USE16
DW 200 DUP(0)
stck ENDS

code SEGMENT USE16 'CODE'
ASSUME CS:code

start:
MOV EBX,4564566
MOV ECX,5

MOV AX,4C00h
INT 21h

Was mache ich falsch? Vielen Dank schonmal für die Hilfe

Soweit ich das sehe, benutzt du 16 Bit-Segmente. 16Bit-Segmente können nicht direkt mit den "großen" Registern EAX, EBX etc. arbeiten, sie brauchen ein Prefix dafür. Dafür sollte der Assembler aber sorgen. In allen anderen Fällen geniert er 16Bit Zugriffe, d.h. das Highword wird 0. Du kannst das mal testen, indem du zwei Sachen änderst.
Entweder...
Ersetze das USE16 durch USE32.
Oder...

probiere folgendes im Code...

db 66h
MOV AX, 12345678h
db 66h
MOV BX, 00000005h


Normalerweise erzeugt ein Assembler aber die nötigen Prefixe... Das mußt du dir mal im Disassemblat anschauen. Und wie gesagt: Du befindest dich für Assembler, Debugger und Prozessor erst mal im 16Bit-Modus! Die erweiterten Register sind zwar da, aber nicht direkt sicht- und benutzbar.

gargyle
16.05.2005, 19:31
@Pukys
Die Anweisungen

db 66h
MOV AX, 12345678h
db 66h
MOV BX, 00000005h

bringen mit sicherheit nicht den gewünschten Erfolg.
Grund:

Der Assembler weis nicht das duch die Anweisung db 66 die Datenbreite geändert wird.
Er wird also eine 16 Bit Anweisung erzeugen.
Die CPU wird aber ein 32 Bit Datenword lesen, und somit die ersten zwei Byte der nächsten Anweisung als Daten lesen.
Mal abgesehen davon lässt sich

MOV AX, 12345678h

gar nicht übersetzen.

Grüße

Pukys
17.05.2005, 09:10
@Pukys
Der Assembler weis nicht das duch die Anweisung db 66 die Datenbreite geändert wird.
Er wird also eine 16 Bit Anweisung erzeugen.
Die CPU wird aber ein 32 Bit Datenword lesen, und somit die ersten zwei Byte der nächsten Anweisung als Daten lesen.
Mal abgesehen davon lässt sich

MOV AX, 12345678h

gar nicht übersetzen.

Grüße

Gewisse Inline-Assembler haben damit keinerlei Probleme. Code dieser Form wurde bei inline-Assembly unter Borland Pascal im flat 16bit mode (Im 386 flat protected mode mit 16Bit Segmenten, bzw. im V86-Modus mit etwas unorthodox gesetzer GDT) üblicherweise eingesetzt.

drstar
22.05.2005, 01:36
Die Lösung ist noch viel einfacher:

mov bx, ffffh
db 66h
shl bx,16
mov bx, eeeeh

danach sollte ffffeeeeh in ebx stehen, selbiges gilt für die exx-Register.
Grund: Es wird zunächst das HÖHERWERTIGE Word geladen, um 16 Bit nach linkls geshiftet (steht also folglich im höherwertigen(!) Teil des EBX-Registers und anschließend wird einfach das niederwertige Word geladen.