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.
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.
@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
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.
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.
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.